A program, like life, is a sum of decisions. Complexity arises when you're forced to make inconsequential decisions. Let's take a concrete example to highlight this.
Printing hard-coded lines on the screen is easy. Although it makes no difference here, the language will still force you to choose between a vector and a list for those lines- an inconsequential decision. Multiply that by the complexity of selecting "an output steam," etc., and you get the point. It's akin to choosing a football jersey: wearing violet over blue will not increase the chance of winning, yet you need to select a color.
Complexity does not arise because of your specific problem but because you need to rephrase it as a specialization of a "general problem" that you need to now learn about. While helping solve a wide variety of problems in a DRY manner, abstractions still introduce a distance between your conceptual solution and the "programmable solution." And that's the source of the apparent complexity.