Is it possible to improve the template template parameter

I know how to improve the forward parameter. However, I read from various sources (for example, “Effective Modern C ++” paragraph 24 “Scott Myers”) that you can only improve when you have the exact name of the template, for example:

template<typename T>
void foo(T&& param) { bar(std::forward<T>(param)); }

I am looking for if there is a way to improve the template template parameter, for example:

template<template<int, class TypeT> class Vector, int Size, typename TypeT>
void foo(Vector<Size, TypeT>&& param) { bar(std::forward<Vector<Size, TypeT>>(param)); }

When I compile the above, I get an error message: "You cannot bind the lvalue value to the rvalue link" (VC12), which tells me that the compiler does not recognize && as a "universal link", but as a rvalue reference. This ideal method may be useful for me, because I can use the derived TypeT and Size.

Question: is it possible to improve the parameters of the direct template template? If so, where is my syntax incorrect?

Thank!

+4
source share
1 answer

A "universal link" (the standard term is link forwarding) is (by definition) a rvalue link to the cv-unqualified template parameter, i.e. T&&.

Vector<Size, TypeT>&& is a rvalue reference, not a forwarding reference.

If you want to get the value of the template arguments, write the attribute:

template<class> struct vector_traits;

template<template<int, class TypeT> class Vector, int Size, typename TypeT>
struct vector_traits<Vector<Size, TypeT>>{
    static constexpr int size = Size;
    using value_type = TypeT;
};

And check std::decay_t<T>:

template<class T>
void foo(T&& t) {
    using TypeT = typename vector_traits<std::decay_t<T>>::value_type;
    // use TypeT.
}

You can also move it to the default template argument, which makes fooSFINAE-friendly (it is removed from the overload set if std::decay_t<T>it is not a "vector"):

template<class T,
         class TypeT = typename vector_traits<std::decay_t<T>>::value_type>
void foo(T&& t) {
    // use TypeT.
}
+5

All Articles