The following template code is buggy as std::array has no operator():
template <typename T> void k(T x)
{
std::array<T, 3> a { x, x, x };
std::cout << a(1) << "\n";
}
int main()
{
// k<int>(5);
return 0;
}
but GCC and CLANG won't say anything about it, until the template is instantiated (uncommenting the first line of main()).
Is this expected behavior? It does not look like SFINAE.
Another case of not using the template is defining a base class template, and overloading one buggy method in an instantiated and derived class. The overloading hides the buggy templated one and I have no GCC or CLANG error, despite the code not being legal.
The following template code is buggy as std::array has no operator():
template <typename T> void k(T x)
{
std::array<T, 3> a { x, x, x };
std::cout << a(1) << "\n";
}
int main()
{
// k<int>(5);
return 0;
}
but GCC and CLANG won't say anything about it, until the template is instantiated (uncommenting the first line of main()).
Is this expected behavior? It does not look like SFINAE.
Another case of not using the template is defining a base class template, and overloading one buggy method in an instantiated and derived class. The overloading hides the buggy templated one and I have no GCC or CLANG error, despite the code not being legal.
Share Improve this question edited Mar 19 at 19:29 TylerH 21.1k79 gold badges79 silver badges114 bronze badges asked Feb 22 at 15:44 Adhémar PatamobAdhémar Patamob 851 silver badge6 bronze badges 10 | Show 5 more comments2 Answers
Reset to default 9With template code you have code that depends on the template parameters, and code that, no matter what template parameters are used, does not depend on the template parameter.
For the dependent code, the code can only be checked so much without knowing the template parameters. There could be a specialization of std::array<T, 3>
which has an operator(integer_type)
defined, so the compiler will ignore that "wrong code" until it knows what the template parameters are
This is why you do not get an error until you use the template. The code inside is considered valid enough because the non-dependent code is valid, and it's only the dependent code that has the issue.
This is because you could make k
valid by specializing std::array
:
struct S {};
namespace std {
template <size_t N>
array<S> {
array(...) {}
int operator(size_t i) const { return i; }
};
}
k(S{}); // prints 1
a(1)
should not be correct for any compiler. Do you meana[1]
or.at(1)
? – Pepijn Kramer Commented Feb 22 at 15:48