tl;dr; I know that C++ can’t do this and I know how to work around it via ADL and am not asking about that. What I don’t know is why the language design chose to (or was forced to) disallow this.
The longer version:
The following code does not work:
template <class T>
struct A { struct R {}; };
void Fn(int);
template <class T>
void Fn(typename A<T>::R v);
////////////////////////////////
void Test() {
A<int>::R v;
Fn(0); // Works
Fn(v); // Fails
}
It fails because the language is unable to infer template argument T
for the template overload of Fn
in order to make typename A<T>::R
into A<int>::R
. For a human, in this case, it’s plainly clear that T
should be int
, but the rules of C++ don’t allow that inference to be made.
My actual question:
What motivated or forced the designer of C++ to impose that restriction?
I suspect that the answer is that “guessing” that a class template will have a nested type before actually resolving it is technically or philosophically problematic, or that implementing that logic in existing compilers was architecturally prohibitive. That said, only the first of those is a fundamental problem and I’m not actually seeing why any of those are necessarily true, and that suggests I’m missing something interesting.