Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

C++ fold expressions, the main C++ feature the article covers, are simple and dumb (at least, enough to use them) but not verbose, and definitely harder to get wrong than a much more verbose for loop.


I love fold expressions, but if you're inside a variadic template, you've long left the realms of "simple and dumb". IMO.

I mean, they're only readable to people who have dabbled in variadic templates in their free time. That's how many people on your (future) team?


> I mean, they're only readable to people who have dabbled in variadic templates in their free time. That's how many people on your (future) team?

This line of reasoning is vacously true for any syntax and semantics though. Move semantics and rvalue reference are only readable to people that have taken the time to understand them -- they're undoubtably useful though.


Move semantics and rvalue references are too complex and error prone to be useful in general code.

It is best to use them only in performance sensitive places and containers.


I strongly disagree. Move Semantics allow you to communicate ownership information at API boundaries with the type system.

C APIs come, of necessity, with tons of documentation about who is deleting what, when. Or, you know, maybe they don't and you have to learn the hard way. std::unique_ptr (implemented with move semantics) largely solves this problem.

And you can imagine notions of ownership more complex than "I'm deleting this at some point" (maybe "I'm versioning this object now, don't worry about it"). If you want to encode these transfers of ownership into your API, that's Move Semantics!


If you read carefully, I said use move semantics to implement containers. That includes std::unique_ptr (a container for pointers with a deleter).

The point is that you shouldn't be using rvalue ref parameters, std::forward, etc. in most of your code. Even std::move should be fairly rare.


Any time you want to pass a named unique_ptr across an API boundary, you'll need to std::move it


...which you should avoid as much as possible do.

Passing std types across API boundaries is a code smell.


What? That's one of the primary motivations!

"I have created an object and will pass its unique ownership to you." -> std::unique_ptr

"This routine needs a function that takes two ints and returns a float (without putting all my code into headers)." -> std::function<float(int, int)>.

Can you elaborate in what circumstance you should not pass std::types across API boundaries?


The heap allocation is an implementation detail.

std::function is useful in some situations, but "without putting all my code into headers" is not a good argument.


Or you know, anyone who has used them in their day job writing C++. Just like literally every language feature.


I just fixed a segfault the other day because one of our new hires fresh from college is eager on using modern c++ and didn't put parentheses at the correct place in his fold expression.


It sounds like an interesting bug, can you elaborate? On the surface it sounds like your new hire merely used fold expressions to call functions and operators that were already treacherous on their own.


Sorry, I can't look it up right now, but trying to reconstruct it in my head it must've been something like

    y = (f(x1), f(x2), f(x3))
vs

    y = f(x1, x2, x3)
Not entirely sure anymore though. But it was something about causing side effects but throwing away return values with the ,-operator and involved function calls, I think


Nothing in templates is 'simple and dumb': it may look so but it isn't: try to write some, you'll inevitably makes some mistake and the errors are really awful!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: