Search code examples
c++templatesc++11rvalue-referencetemplate-templates

Template template functions and parameters deduction


I've got a problem with template templates and parameters deduction. Here's the code:

template<typename U, template<typename> class T>
void test(T<U>&& t)
{
  ...
}

I expected this to accept either lvalues and rvalues, but only works with rvalues. The collapsing rule "T& && = T&" doesn't apply in this case?

Naturally I could declare the lvalue reference function too, but makes the code less readable.

If you're asking why I need this is to use a static_assert to check if T is a particular class. If there's a simpler way to do so I'll be happy to change my code, but I'd like to know if template templates are usable in this way.

Thanks


Solution

  • Unlike typename T, which can be deduced to be a reference type, template<typename> class T can only ever be deduced to be a class template, so T<U> is always deduced to an object type.

    You can write your function templated on T then unpack the template type in the static_assert:

    template<typename T> struct is_particular_class: std::false_type {};
    template<typename U> struct is_particular_class<ParticularClass<U>>: std::true_type {};
    
    template<typename T> void test(T &&) {
      static_assert(is_particular_class<std::remove_reference<T>::type>::value, "!");
    }