I was researching on two phase name lookup. A very logical explanation shows that one of the main reasoning for it is that follows the C++ philosophy of catching errors as early as possible.
My question is why isn't this philosophy followed with non-templated methods. Instead of checking when and if the method is called, why not check all non-templated methods in phase 2 when the templated class is instantiated?
E.g.:
template <class T>
struct X {
auto foo() // non-templated (important)
{
T t{};
return t.non_existing();
}
};
int main()
{
X<int> x; // (1) this compiles OK.
// somewhere is a galaxy far far away,
// maybe deep inside some unrelated code
x.foo(); // (2) the error is here
}
If you never write (2) the program compiles and runs without any problems, although foo
is illegal for the instantiated X<int>
.
I think that the line (1) should generate error, regardless if you ever call foo
or not.
When writing templated classes, this can let slip through the cracks an error until you finally call that problematic method (2), instead of getting the error when you instantiate the templated class (1).
Also sanity check: is the code valid if I instantiate X<int>
(1) but never call X<int>::foo
(2)? Or is it something like "ill-formed, no diagnostics required"? If the latter, then this is an even more reason to catch the error earlier.