5 ms·
> move semantics Move semantics have been great, in my experience (enabling things like unique_ptr). What is causing issues here?
by santaclaus 10y ago
> move semantics
Move semantics have been great, in my experience (enabling things like unique_ptr). What is causing issues here?
- fauigerzigerk 10y agoMove semantics are very useful, but there's also something wrong if articles like this are necessary or even possible: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers https://isocpp.org/blog/2012/11/universal-references-in-c11-...
- bsaul 10y agoOh gosh... how come does anyone not realize what a dead end a language has become once this kind of article needs to be written ?
- jasode 10y agoScott Meyer's articles (and numerous video presentations) on Universal References are educational but he doesn't make it clear to the audiences the bigger picture of where and why they'd need to really learn it. The Forwarding Reference (aka Universal Reference) is for programmers writing generic templates. A lot of C++ programmers can do a ton of productive work and get by for years without writing any templates from scratch. Yes, they use others' templates (such as STL/Boost libraries) but they don't necessarily write their own. I have no survey data but I'll take a wild guess that less than 1% of C++ programmers need to memorize template Forward References. As an analogy using the plain C Language, it's as if someone created very prominent blogs about the complexity of "char ∗(∗(∗a[])())()" with long paragraphs explaining how it's "an array of pointers to functions returning pointer to function returning pointer to char". If that type of essay had a lot of visibility, people might think that "Wow the C Language is difficult and too complicated!" In reality, a lot of C programmers don't write complex declarations like that. The more common pointer-to-function for something like qsort() is very easy to write.
- HelloNurse 10y ago" A lot of C++ programmers can do a ton of productive work and get by for years without writing any templates from scratch" as well as people who choose not to have a stove or oven in their kitchen can eat, but with the delusion that they are smartly avoiding difficulties.
- fauigerzigerk 10y ago"char ∗(∗(∗a[])())()" may have entertainment value in an obfuscated C contest, but it is otherwise useless. Using && in templates may be advanced C++, but it is both useful and mainstream. You're essentially saying, "don't worry, no one uses the new language features anyway". But that's not a convincing response to a complaint about the incredible complexity introduced by a particular new language feature.
- jasode 10y ago>You're essentially saying, "don't worry, no one uses the new language features anyway". No, I'm not saying that. A lot of C++ programmers are application programmers who glue together Qt GUI with some code to read a TCPIP socket or file and write out some data. Many C++ programmers simply don't have the day-to-day need to write generic templates (libraries). Yes, it may be useful and mainstream to you but I don't think that is reflective of the whole C++ programming community at large. >But that's not a convincing response to a complaint about the incredible complexity introduced by a particular new language feature. When I studied it, the "&&" syntax and type deduction rules seem to be "irreducible complexity". Every computer science problem that involves one set of syntax to write another syntax (meta template programming) is complicated. This includes XSLT to rewrite XML, or PHP code that dynamically writes javascript syntax embedded inside of HTML syntax. Reading any of that code-that-writes-code is always ugly. If we were to challenge a language designer to recreate a syntax that meets the same exact goals of C++ (perfectly pass parameters without casts, no unnecessary copies that kills performance, with static type checks, etc), he'd eventually end up at the same complexity you have now. In other words, there is no breakthrough A.I. compiler algorithm that lets the parser correctly infer how parameters pass through to generic code. If there's a whitepaper that claims otherwise, I'd love to read it. (Rust generics are simpler but they also do less than C++ templates.) The TLDR is that C++ templates is a code gen tool and like any other nontrivial code gen tool, they end up being complicated.
- CJefferson 10y agoMy personal main problem is things like you can't template on an r-value reference, as T&& in a template matches both r-value and l-value references and then you need std::forward or std::move and then I start getting confused. I wish in templates they had gone with the suggestion I saw to use T&&& to mean "r-value or l-value reference", and then let T&& just mean "r-value reference".
- ytugiuyghvk 10y agoIf you want to template on an r-value reference, the easiest way is probably to use a forwarding reference and disable the template if the template parameter deduces to a reference template <class T, class = enable_if_t<!is_reference<T>::value>> auto f(T&& x);
- weerd 10y agoIs this C++14? Can you please explain the "class = ..." template parameter?
- ytugiuyghvk 10y agoclass = X is just an anonymous template type parameter with default value X, just like auto foo(int = 0); declares a function with a int parameter with default value 0. In this case, it's just a conventional place to stick an expression in the declaration to trigger SFINAE. If you don't need SFINAE, you can also just place the condition in a static_assert in the definition template <class T> auto foo(T&&) { static_assert(!is_reference<T>::value, "call me with an r-value"); ... }
- StephanTLavavej 10y agoYes, that's C++14. First, "class = enable_if_t<!is_reference<T>::value>" is just "class Dummy = enable_if_t<!is_reference<T>::value>" that doesn't bother to name Dummy. It's providing a default template argument for a function template (this is a C++11 feature; in C++03, only class templates could have this). Next, "enable_if_t<!is_reference<T>::value>" is a C++14 library feature (enable_if_t is an alias template; the Core Language gained alias templates in C++11, the library gained these in C++14). It is a synonym for "typename enable_if<!is_reference<T>::value>::type", which is more verbose (and what one had to type in C++11). "is_reference<T>::value" is a C++11 type trait, that is true when T is X& or X&&, and false otherwise. (It's implemented with partial specializations, and a "static const bool value = true;" data member - actually constexpr these days, but no difference there. This is type traits 101.) enable_if is a library helper for SFINAE. (Not necessarily C++11 Expression SFINAE; here, just C++03 classic SFINAE is being used.) Basically, enable_if<true>::type is void. enable_if<false>::type doesn't exist. This works with the Core Language's SFINAE rules to make function templates vanish from the overload set (if you don't know what SFINAE is, look it up; it's a little complicated, but it exists for good reasons, and it goes back to C++98). So, this is how one writes a function template that vanishes under certain criteria. This is often desirable compared to doing different things for different types (that can often be done with "tag dispatch") or emitting compiler errors for certain types (that's a static_assert).
- KKKKkkkk1 10y agoI'm having trouble understanding the differences between a * and a &, and now with move semantics we have stuff like &&, && &, and && &&. Please stop!