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?
This is CWG1391:
It is possible that you are bitten by DR #1844. In [temp.deduct]/8 it states:
The problem here is that "immediate context" is not really given a definition, leading to variance among compilers.