Movatterモバイル変換


[0]ホーム

URL:


Issue 176 - WG21 CWG Issues
Title
Name injection and templates
Status
tc1
Section
Clause [11] [class]
Submitter
John Spicer

Created on1999-02-21.00:00:00 last changed277 months ago

Messages

msg310 (view)
Date: 2000-10-15.00:00:00

Proposed resolution (10/00):

[Note: these changes depend on the resolution forissue 147.]

Replace 13.8.2 [temp.local] paragraphs 1 and 2 with thefollowing:

Like normal (non-template) classes, class templates have aninjected-class-name (Clause 11 [class]). Theinjected-class-name can be used with or without atemplate-argument-list. When it is used without atemplate-argument-list, it is equivalent to theinjected-class-name followed by thetemplate-parameters of theclass template enclosed in<>. When it is used with atemplate-argument-list, it refers to the specified classtemplate specialization, which could be the current specialization oranother specialization.

Within the scope of a class template specialization or partialspecialization, when the injected-class-name is not followed by a<, it is equivalent to the injected-class-name followed bythetemplate-arguments of the class template specialization orpartial specialization enclosed in<>.[Example:

    template<class T> class Y;    template<> class Y<int> {        Y* p;          //meaning Y<int>        Y<char>* q;    //meaning Y<char>    };

end example]

The injected-class-name of a class template or class templatespecialization can be used either with or without atemplate-argument-list wherever it is in scope.[Example:

    template <class T> struct Base {        Base* p;    };    template <class T> struct Derived: public Base<T> {        typename Derived::Base* p;  //meaning Derived::Base<T>    };

end example]

A lookup that finds an injected-class-name (6.5.2 [class.member.lookup]) can result in an ambiguity in certain cases (forexample, if it is found in more than one base class). If all of theinjected-class-names that are found refer to specializations of thesame class template, and if the name is followed by atemplate-argument-list, the reference refers to the classtemplate itself and not a specialization thereof, and is notambiguous. [Example:

    template <class T> struct Base { };    template <class T> struct Derived: Base<int>, Base<char> {        typename Derived::Base b;            //error: ambiguous        typename Derived::Base<double> d;    //OK    };

end example]

When the normal name of the template (i.e., the name from theenclosing scope, not the injected-class-name) is used without atemplate-argument-list, it refers to the class template itselfand not a specialization of the template. [Example:

    template <class T> class X {        X* p;         //meaning X<T>        X<T>* p2;        X<int>* p3;        ::X* p4;      //error: missing template argument list                      // ::Xdoes not refer to the injected-class-name    };

end example]

msg255 (view)
Date: 2022-02-18.07:47:23

There is some controversy about whether class name injection appliesto class templates. If it does apply, what is injected? Is a classname injected or is the thing that is injected actually a template?

Clause 11 [class] paragraph 2says,

Theclass-name is also inserted into the scope of the classitself.
In general, clause 9 applies to both classes and class templates, so Iwould take this to mean that class name imjection does indeed apply toclass templates. One problem with this is that clause 9 uses thesyntactic termclass-name, which I would take to imply that theinserted name is always a class. This is clearly unacceptable forclass templates as it makes the template itself unusable from with thetemplate. For example:
    template <class T> struct A {        A<T*> ptr;    // Invalid: A refers to a class    };

Clearly the injected name must be usable as both a class and aclass template. This kind of magic already exists in the standard.In 13.8.2 [temp.local] it says,

Within the scope of a class template, when the name of the template isneither qualified nor followed by<, it is equivalent tothe name of the template followed by thetemplate-parameters enclosed in <>.

The proposal here is that we clarify that name injection doesindeed apply to class templates, and that it is the injected name thathas the special property of being usable as both a class and atemplate name (as described in13.8.2 [temp.local]). This would eliminatethe need for special wording regarding the qualification of the name,but would achieve the same result. This would also make this"special" name available to a derived class of a class template— something which is necessary if the benefits of class nameinjection are to be made uniformly available for class templates, too.

    template <class T> struct Base {        Base* p;        Base<T*>* p2;        ::Base* p3;    // Error: only injected name usable as class    };    template <class T> struct Derived: public Base<T> {        Base* p;    // Now okay        Base<T*>* p2;    // Still okay        Derived::Base* p3;    // Now okay
Note that by giving the special attribute of being usable as both aclass and a template to the injected name it is now clear where thisattribute can and cannot be used.

(See paper J16/99-0010 = WG21 N1187.)

History
DateUserActionArgs
2003-04-25 00:00:00adminsetstatus: dr -> tc1
2000-11-18 00:00:00adminsetstatus: ready -> dr
2000-05-21 00:00:00adminsetmessages: +msg310
2000-05-21 00:00:00adminsetstatus: open -> ready
1999-02-21 00:00:00admincreate

[8]ページ先頭

©2009-2026 Movatter.jp