What is wrong with the following piece of code?
#include <iostream> template<typename K> struct A { struct X { K p; }; struct Y { K q; }; }; template<typename K> void foo(const typename A<K>::X& x, const typename A<K>::Y& y) { std::cout << "A" << std::endl; } int main() { A<float>::X x; A<float>::Y y; foo(x, y); }
clang gives the following error message:
17:2: error: no matching function for call to 'foo' foo(x, y); ^~~ 10:6: note: candidate template ignored: couldn't infer template argument 'K' void foo(const typename A<K>::X& x, const typename A<K>::Y& y) { ^ 1 error generated.
The argument K
in const typename A<K>::X
is not deducible. Basically, everything left of a ::
is not deducible (if ::
separates a nested-name).
It's trivial to see why it makes no sense to ask for deduction by running through this thought experiment:
struct A { typedef int type; } struct B { typedef int type; } template <typename T> void foo(typename T::type); foo(5); // is T == A or T == B ??
There's no one-to-one mapping from types to nested types: Given any type (such as int
), there could be many ambient types of which it is a nested type, or there needn't be any.
template<typename K> void foo(const typename A<K>::X& x, const typename A<K>::Y& y) { std::cout << "A" << std::endl; }
K
cannot been deduced, since it's in non-deduced
context.
n3337 14.8.2.5/4
In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
n3337 14.8.2.5/5
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a qualified-id.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With