From n4459 :
635. Names of constructors and destructors of templates
There is a discrepancy between the syntaxes allowed for defining a constructor and a destructor of a class template. For example:
template <class> struct S { S(); ~S (); }; template <class T> S<T>::S<T>() { } // error template <class T> S<T>::~S<T>() { } // okay
The reason for this is that 3.4.3.1 [class.qual] paragraph 2 says that S::S is “considered to name the constructor,” which is not a template and thus cannot accept a template argument list. On the other hand, the second S in
S::~S
finds the injected-class-name, which “can be used with or without a template-argument-list” (14.6.1 [temp.local] paragraph 1) and thus satisfies the requirement to name the destructor's class (12.4 [class.dtor] paragraph 1).
I don't understand, What does say that S::S
is “considered to name the constructor,” which is not a template ?
S::S is “considered to name the constructor,” which is not a template and thus cannot accept a template argument list
Yes, it is possibly because a constructor might be templated. So by preventing non-template constructor to not have S<T>::S<T>
syntax, the language reserves this syntax for the templated constructor.
Here is an example:
template <typename T>
struct X
{
template<typename U>
X();
~X ();
};
template <typename T>
template <typename U>
X<T>::X<U>() { } //OK now
template <class T>
X<T>::~X<T>() { } // okay
If the syntax S<T>::S<T>()
was allowed, then in this case you would have to write X<T>::X<T><U>()
— that is an ugly and a new syntax. So in a sense, by preventing this, the syntax is slightly cleaner and that also avoids introducing a new syntax.
On the other hand, the destructor can never be a template.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.