Specialty

g ++ 3.4.5 accepts this code:

template <typename T> struct A { static const char* const str; }; struct B {}; typedef A<B> C; template<> const char* const C::str = "B"; // Equivalent to following? // template<> const char* const A<B>::str = "B"; 

But I'm not sure if this is really legal C ++ 03. In particular,

[14.7p3] In an explicit specialization declaration for a class template, class template member, or class member template, a class name that is explicitly specialized must be the template identifier.

Does this mean that the non-typedef version should be used at the end of this example? Or am I misinterpreting something?

Edit: additional evidence: 403 defects report assumes that it is incorrect to indicate the type (in this context, the argument type is the expression of the function call) is the identifier of the template, because the template identifier has a syntactical value, and not semantic. Later drafts of the Standard used the "template template specification" instead of the "template-id" in 3.4.2.

This supports the argument that although A<B> and C are of the same type (and have the same or almost identical meaning), A<B> is the identifier of the template, and C not, because the term template -id refers to the syntax content as a sequence of tokens, not the meaning of these tokens.

+4
source share
2 answers

I think this is strictly poorly formed (at least according to C ++ '03).

My logic is that although typedef (7.1.3 / 1):

... is thus a synonym for another type.

There are still words in the standard that allow explicit use of typedef, where class-name (7.1.3 / 4) is required:

The typedef name calling the class is the name of the class

There are no such words for template-id .

+4
source

I assume that explicit specialization is not the case here. You can write similar code without templates:

 struct A { static const char* const str; }; typedef AC; const char* const C::str = "B"; 

This code is absolutely correct, even if you use C instead of A. C is just an alias.

Imagine how C ++ code is handled. The types are obviously extended by the compiler before the template creation process even began. Same as all comments before macros. Since all macros are extended by the preprocessor before C ++ parsing begins. It simplifies everything.

Regarding the C ++ 03 standard, look at this

7.1.3 / 1 A name declared with the typedef specifier becomes a boolean name. As part of the declaration, typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in the manner described in 8. Thus, typedef-name is a synonym for another type. typedef-name does not introduce a new enter method for declaring a class (9.1) or enum.

I think this paragraph clearly explains that C in your code is actually a template identifier.

0
source

Source: https://habr.com/ru/post/1332394/


All Articles