I have the following piece of code:
template<class A>
struct X {
template<class T>
X(T t) {}
};
template<class A>
void f(X<A> x, A a) {}
int main() {
f(0, 0);
}
which fails to compile (gcc 14.1.1) with the following error:
test.cc:20:10: error: no matching function for call to ‘f(int, int)’
20 | f(0, 0);
| ~^~~~~~
test.cc:17:6: note: candidate: ‘template<class A> void f(X<A>, A)’
17 | void f(X<A> x, A a) {}
| ^
test.cc:17:6: note: template argument deduction/substitution failed:
test.cc:20:10: note: mismatched types ‘X<A>’ and ‘int’
20 | f(0, 0);
| ~^~~~~~
If I understand correctly, any value should be convertible to X<A> because of the templated constructor X(T)
What's interesting though is that the static_assert doesn't cause a compile-time error:
static_assert(std::is_convertible_v<int, X<int>>); // no assertion failure
How can I change the program to keep both templates and allow conversions to X?
AinX<A>from0. What you can do it to disable deduction forX<A>using a standard trick:void foo(std::type_identity_t<X<A>> x, A a).