News for hackers. Stuff that matters.
Re:C++11 FAQ by CJefferson on Thursday January 26, 2017 @10:53AM (#13492336)
My 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".

Re:C++11 FAQ by ytugiuyghvk on Thursday January 26, 2017 @11:14AM (#13492547)
If 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);
Re:C++11 FAQ by weerd on Thursday January 26, 2017 @11:45AM (#13492866)
Is this C++14? Can you please explain the "class = ..." template parameter?
Re:C++11 FAQ by StephanTLavavej on Thursday January 26, 2017 @12:52PM (#13493491)
Yes, 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).

Re:C++11 FAQ by ytugiuyghvk on Thursday January 26, 2017 @12:44PM (#13493423)
class = 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");
        ...
    }