admin管理员组

文章数量:1287990

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 tell it, until the template is instantiated (uncommenting the first line of main()).

Is it an expected behavior ? It does not look like a SFINAE.

Another case of not using the template is defining a base class template, and overloading one buggy method in a instantiated and derived class. The overloading hides the buggy templated one and I have no GCC nor CLANG error, despite the code being not 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 tell it, until the template is instantiated (uncommenting the first line of main()).

Is it an expected behavior ? It does not look like a SFINAE.

Another case of not using the template is defining a base class template, and overloading one buggy method in a instantiated and derived class. The overloading hides the buggy templated one and I have no GCC nor CLANG error, despite the code being not legal.

Share Improve this question asked Feb 22 at 15:44 Adhémar PatamobAdhémar Patamob 851 silver badge6 bronze badges 10
  • a(1) should not be correct for any compiler. Do you mean a[1] or .at(1) ? – Pepijn Kramer Commented Feb 22 at 15:48
  • 1 related/ maybe dupe: stackoverflow/questions/77834724/… – NathanOliver Commented Feb 22 at 15:49
  • 1 I mean a(1) : it is not legal but it compiles, so I'm disappointed – Adhémar Patamob Commented Feb 22 at 15:49
  • 1 There's also Why does this compile when I make the class a template? but the current question has garnered more detailed answers than the old question. – JaMiT Commented Feb 22 at 16:35
  • 1 A template is like a macro, but part of the core language rather than the preprocessor. Just as an malformed macro may not be noticed until it is substituted, a non-viable template may not be detected until it is instantiated. – Eljay Commented Feb 22 at 18:58
 |  Show 5 more comments

2 Answers 2

Reset to default 9

With template code you have code that depends on the template parameters, and code that no matter what template parameters are used, that 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

本文标签: when the C compiler shall check for template correctnessStack Overflow