Consider following code:
#include <type_traits>
template <typename T> struct A
{
static_assert(!std::is_same_v<int, T>);
};
template<typename T> struct B
{
void foo()
{
A<int>{};
}
};
int main() {}
It comes from this question on russian StackOverflow, which asks whether it's valid or not.
I attempted to reference this:
[temp.res]/8.1
8 The validity of a template may be checked prior to any instantiation. [ Note: Knowing which names are type names allows the syntax of every template to be checked in this way. — end note ] The program is ill-formed, no diagnostic required, if:
(8.1) — no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
...
(emphasis mine)
Since no valid specialization can be generated for foo()
, I reasoned that the snippet is ill-formed, NDR.
But I was told [temp.res]/8.1
doesn't apply since foo()
itself isn't a template member function.
cppreference calls non-template member functions of template classes "templated entities", but it seems to be unclear if they can be considered templates themselves.
Thus, the question is: Does the standard consider non-template members of template classes to be "templates" themselves?
This is essentially CWG issue 1253
Generic non-template members
Section: 17.8 [temp.spec] Status: drafting Submitter: Nikolay Ivchenkov Date: 2011-03-06
Many statements in the Standard apply only to templates, for example, 17.7 [temp.res] paragraph 8:
If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.
This clearly should apply to non-template member functions of class templates, not just to templates per se. Terminology should be established to refer to these generic entities that are not actually templates.
It appears to be still in drafting. But I'd argue, like the issue, that the code in the OP should be ill-formed NDR as well. Even if the member function is never used (and therefore its full definition is never instantiated), it still cannot be even hypothetically instantiated, which puts it under the category of errors [temp.res]/8 is meant to cover.
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