2010-10-11 2 views
4

У меня есть следующий код тестаоператор разрешения области видимости и зависит имя

#include <iostream> 
template <typename T> 

struct PS 
{ 
    template <typename U> 
    static void foo() 
    { 
     std::cout<<"Some test code"; 
    } 
}; 

template <typename T> 
void bar() 
{ 
    PS<T>::template foo<T>(); //won't compile without `::template` 
} 

int main() 
{ 
    bar<int>(); 
} 

ISO C++ 03 14.2/4: говорит

Когда имя шаблона член специализации появляется после. или -> в постфиксном выражении или после вложенного имени-спецификатора в квалифицированном-id, а постфикс-выражение или квалифицированный-ящик явно зависит от параметра-шаблона (14.6.2), имени шаблона должен быть префикс шаблона ключевого слова. В противном случае предполагается, что имя называется не-шаблоном.

Стандарт говорит о -> и ., но не о ::. Это дефект в стандарте C++ 03, или я что-то упускаю? Кто-нибудь, пожалуйста, просветите меня.

Однако формулировка была изменена в N3126

Когда на экране отображается название шаблона члена специализации после . или -> в постфиксном выражении или после специфицированного вложенного имени в квалификационном идентификаторе, а выражение объекта или указателя постфиксного выражения или вложенного имени в квалификационном идентификаторе зависит от шаблона параметр (14.6.2) , но не относится к члену текущего экземпляра (14.6.2.1), имя шаблона члена должно быть , предварительно заданное шаблоном ключевого слова. В противном случае предполагается, что имя называется не-шаблоном.

Может ли кто-нибудь привести пример, чтобы проиллюстрировать, что означает but does not refer to a member of the current instantiation в контексте C++ 0x?

-PS

ответ

6

Стандарт говорит о -> и ., но не о ::.

Оператор разрешения области видимости (::) является часть квалифицированного идентификатора, на которые ссылаются «или после того, как -имя вложенного-спецификатор в квалифицированного идентификатора

Дополнительная формулировка в C++ 0x является частью разрешения до CWG defect 224. Фактически, было изменено определение зависимых имен:

Решение о том, зависит ли имя или не зависит от имени, должно основываться на поиске, а не на форме имени: если имя может быть просмотрено в контексте определения и не может быть чем-либо еще в результате специализации, имя должно быть не зависящим.

+1

Обратите внимание, что использование «квалифицированного идентификатора» в стандарте неверно во многих местах, поэтому лучше не брать его по слову, когда говорит «квалифицированный идентификатор». Например, в следующем объявлении переменной вам нужен ':: template', но спецификатор вложенных имен не отображается в идентификаторе с квалификацией (но вложен в« спецификатор типа »):' typename T :: template alloc a; '. Фактически, использование «квалифицированного идентификатора» в стандарте чаще всего отражает намерение «квалифицированное имя». –

3

Может кто-нибудь дать пример, чтобы проиллюстрировать то, что «но не относится к члену текущего экземпляра» означает в контексте C++ 0x?

Я не знаю, является ли это то, что на самом деле ведет себя по-разному между реализацией C++ 03 и C++ 0x.

template< typename Q > 
struct A { 
    template< typename T > 
    void f(T); 

    void g() { 
     this->f<Q>(5); // member of current instantiation is not ambiguous 

     A< identity<Q> >().template f<5>(); // suppose A is partially 
// specialized on identity. Legal but confusing; need help from template keyword. 
    } 
}; 
Смежные вопросы