c++ - What are the use cases of not declaring the name for a typename in template? -


sometimes see below kind of declaration:

template<typename>  // <-- not "typename t" struct { ... }; 

what use-cases such declaration. useful or matter of style ?

did see use template definition, , not for, say, template declaration (only)?

some uses:

// declaration only: parameter name has no use beyond documentation template<typename> struct a;  // fine template<typename t> void eat_an_a(a<t> a);  // later, can name parameter use template<typename t> struct { ... };  // c++0x template<     typename t     // don't care actual type (which default void)     // goal sfinae     , typename = typename std::enable_if<         std::is_array<typename std::decay<t>::type>::value     >::value > void f(t&& t);  // still don't care name defaulted parameter template<typename t, typename> void f(t&& t) { ... } 

the explanation particular case linked has been given johannes, apparently have found unsatisfactory. i'm going walk through how works. let assume arbitrary traits class:

// no definition template<typename typetoexamine, typename implementationdetail = void> struct trait; 

i'm spelling out role of type parameters in names. declaration allows, since second parameter defaulted, bit of syntactic sugar. wherever trait<u> appears, it's exactly if we've written trait<u, void> had been written. let provide definition base case of our trait:

// assume previous declaration still in scope not default // second parameter again template<typename t, typename> struct trait: std::false_type {}; 

it's not useful trait. when write trait<u>, short trait<u, void>, end definition. means trait<u>::value valid , in fact false. let's make our class more useful adding secret ingredient:

template<typename> struct void_ { typedef void type; }; // again, assume previous declarations in scope template<typename t, typename void_<decltype( t() + t() )>::type> struct trait: std::true_type {}; 

again, when write trait<u>, it's if we'd written trait<u, void>. partial specialization doesn't change (it's not allowed to). definition should use when query trait<u>::value? well, first, have know specialization shoud match; or, mysterious second argument typename void_<decltype( t() + t() )>::type?

the simplest case when u() + u() ill-formed. sfinae kicks in , it's if specialization didn't exist; non-specialized definition, , value false. if u() + u() well-formed, decltype yields type, , whole turns void, since types void_<t>::type void. means have specialization of form trait<t, void>. can match trait<u>, matching t u. , value true.

if specialization have been written

template<typename t> struct trait<t, decltype( t() + t() )>: std::true_type {}; 

then way used when writing trait<u, decltype(u() + u())>, unless decltype(u() + u()) happended void. remember, trait<u> sugar trait<u, void>. trait<int> never match our specialization because latter of form trait<int, int>.

thus void_ plays role have specializations of form trait<t, void> if not sfinae'd out. since don't care use type parameter, it's not named.


Comments

Popular posts from this blog

c++ - Is it possible to compile a VST on linux? -

java - Output of Eclipse is rubbish -

jquery - Confused with JSON data and normal data in Django ajax request -