C++ standard requirements to templates that are not instantiated

239 views Asked by At

So I tried to compile the code below and it failed (as expected):

1.cpp: In function ‘int foo()’:
1.cpp:3:5: error: ‘some’ was not declared in this scope
     some ill-formed code
     ^

But if I remove this line the compiler compiles it without any errors (also expected as it is unknown whether the T type has random_name() method or not).

It seems that diagnostic for templates that are not used (not instantiated) is implementation defined to some extent. But perhaps the standard has some requirements for such cases. For example would it conform to the standard to compile the code below without any errors?

I tried to search for the answer on the site but could not find any related questions.

template <class T>
int foo() {
    some ill-formed code
    return T::random_name();
}

template <>
int foo<int>() { return 0; }

int main() {
    return foo<int>();
}
2

There are 2 answers

5
Shafik Yaghmour On BEST ANSWER

This is a quality of implementation issue, it is ill-formed but if it is not instantiated no diagnostic is required as per [temp.res#8.1]p:

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:

  • 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

and we can see from this live godbolt example MSVC does not diagnose this case. This is because MSVC is not using two-phase lookup but using /permissive- changes this. clang even has an MSVC compatibility mode to emulate this using -fdelayed-template-parsing.

We can see from this live godbolt using these two options clang no longer produces a diagnostic but MSVC does.

1
Dietmar Kühl On

Names inside a function template are either dependent, i.e., the entity depends on the template parameters in some form, or they are independent, i.e., there is no indication that it depends on a template parameter. Independent names are looked up when the function template is defined. Dependent names are looked up during template instantiation, i.e., at the name doesn’t need to be defined when the function template is defined. Failure to look-up a name is an error. The details of this process are a bit more involved and fill most of the chapter on templates.

In your case some is an independent name while the T:: qualification makes random_name a dependent name.