Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template Argument Deduction Failure and Function Parameters/Arguments Mismatch

Consider the following program:

template <class T> struct A { using X = typename T::X; };
template <class T, typename A<T>::X* = nullptr> void f(T, int);
void f(...);
template <class T> void g(T, int, typename A<T>::X* = nullptr); // #
void g(...);

int main() {
  // f(0, nullptr); // error
  g(0, nullptr); // ok       
}

g(0, nullptr) compiles while f(0, nullptr) does not (tested under GCC trunk and Clang trunk on Godbolt). It seems that during the template argument deduction process of #, the compiler does not instantiate A<int> when it finds the argument nullptr does not match the parameter int. Where does the standard specify this behavior?

like image 284
xskxzr Avatar asked Oct 27 '18 18:10

xskxzr


People also ask

What is template argument deduction?

Template argument deduction is used in declarations of functions, when deducing the meaning of the auto specifier in the function's return type, from the return statement.

What is type deduction c++?

Type inference or deduction refers to the automatic detection of the data type of an expression in a programming language. It is a feature present in some strongly statically typed languages. In C++, the auto keyword(added in C++ 11) is used for automatic type deduction.


2 Answers

It is possible that you are bitten by DR #1844. In [temp.deduct]/8 it states:

If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments. [ Note: If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution process. — end note] Only invalid types and expressions in the immediate context of the function type, its template parameter types, and its explicit-specifier can result in a deduction failure. [ Note: The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]

The problem here is that "immediate context" is not really given a definition, leading to variance among compilers.

like image 23
user10568656 Avatar answered Oct 23 '22 19:10

user10568656


This is CWG1391:

If deduction succeeds for all parameters that contain template-parameters that participate in template argument deduction, and all template arguments are explicitly specified, deduced, or obtained from default template arguments, remaining parameters are then compared with the corresponding arguments. For each remaining parameter P with a type that was non-dependent before substitution of any explicitly-specified template arguments, if the corresponding argument A cannot be implicitly converted to P, deduction fails.

like image 65
T.C. Avatar answered Oct 23 '22 19:10

T.C.