Search code examples
c++c++11templatesrvalue-referencereference-collapsing

reference collapsing with template template class


Why reference collapsing does not apply in

template<typename T, template<typename> class C>
void f(C<T> && x); // x declaration is an rvalue!

How can I perfect forward and how can I avoid overloading all combinations of const lvalue ref, lvalue ref, rvalue ref in

template<typename T> // not necessary a template template class here
void f(C<T>, C<T>, C<T>, ..., C<T>)
{
    // do something with T
    // move or copy arguments to a function
}

Solution

  • You will ned to use some kind of SFINAE, unfortunately

    template<typename T>
    struct HasOneTypeParam : std::false_type { };
    
    template<typename T, template<typename> class C>
    struct HasOneTypeParam<C<T>> : std::true_type { };
    
    template<typename ...T>
    struct SlurpThemAll { typedef int type; };
    
    template<typename ...T, 
      typename SlurpThemAll<
         bool[HasOneTypeParam<typename std::decay<T>::type>::value * 2 - 1]...
         >::type = 0>
    void f(T &&... x);
    

    Depending on what you actually want to do, you can require all of the std::decay<T>::type to be the same type with some more SFINAE hacks.