Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is template-name<TT> a deduced context?

[temp.deduct.type] paragraph 8 lists all deduced contexts, but it seems not to include template-name<TT> where template-name refers to a class template and TT refers to a template template argument. Is this a deduced context?

If it is, why?

If not, consider the following code:

template<template<typename> class U, template<typename> class V>
struct foo {};

template<template<typename> class U>
struct foo<U, U> {}; 

int main() {}

This code compiles under Clang 7.0.0 and GCC 8.0.1, which means the compilers consider the partial specialization is more specialized than the primary template, which means U and V in the primary template are successfully deduced against foo<U, U>. Is this a compiler bug?

like image 559
xskxzr Avatar asked Feb 21 '18 06:02

xskxzr


People also ask

What is template argument deduction?

Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.

What is a template template parameter in C++?

In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Which is a correct example of template parameters?

Template Parameters: These names are listed after the template keyword in a template declaration. For example, T is the single template parameter specified in our Stack example given earlier. Template Arguments: These entities are substituted for template parameters during specialization.

What is template argument list?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)


1 Answers

This paragraph is full of problems, including the one you pointed out. Core issue 2328 has a nice list:

The presentation style of 17.9.2.5 [temp.deduct.type] paragraph 8 results in a specification that is unclear, needlessly verbose, and incomplete. Specific problems include:

  • What does it mean for P and A to have one of a set of forms? Do they both have to have that form? (That doesn't happen; typically, only P contains template parameters)

  • In the introductory sentence, aren't T, TT, and i supposed to be the names of template parameters rather than template arguments?

  • In T[i], it appears we can deduce i, but not T (T can only be deduced in the form T[integer-constant])

  • What is an integer-constant supposed to be?

  • What is a cv-list?

  • Why can we not deduce const T from T? (Apparently you only get to deduce if both or neither type have a cv-list, whatever a cv-list is.)

  • We have extreme redundancy because, for instance, there is no way to say “in T (T::*)(T), you can deduce any of those Ts, and it's OK if some of the positions don't have a T”. So we have seven (!) forms of that construct, for all cases except the one where none of the three positions contain a T.

  • We have special case rules for pointers to member functions, even though they're not a special case and should be covered by the rule for pointers to members and the rule for functions.

  • We do not allow deducing a template template parameter's value from a template template argument — there is a TT<T> form, a TT<i> form, a template-name<T> form, and a template-name<i> form, but no TT<TT> form nor template-name<TT> form.

It looks like the editor managed to get rid of cv-list, at least, since the issue was filed. It's now just cv. (cv-list is kind of hilariously wrong, because [syntax] says that the -list suffix is for comma-separated lists...)

like image 56
T.C. Avatar answered Oct 11 '22 23:10

T.C.