Возможные формы аргумента шаблона шаблона в экземпляре шаблона

Одной из возможных форм параметра шаблона является шаблон класса. В стандарте C++ (C++2003) указано, что аргументом параметра шаблона шаблона во время создания экземпляра шаблона является "id-выражение". Этот нетерминал довольно широк. Он допускает деструкторы, перегруженные операторы и т. д. Например, следующий код должен нормально компилироваться:

template <template <typename x> class T>
struct MyClass
{
    T<int> a;
    T<double> b;
};

template <typename x> struct Helper
{
    ~Helper() { }
    x operator+(x p) { return(x[1]+p); }
    x[4] c;
};

 MyClass<Helper> p1;
 MyClass<~Helper> p2;
 MyClass<Helper::operaror+> p3;

Последние 2 строки не имеют никакого смысла. Но с точки зрения грамматики они прекрасны. Грамматика не является (и не должна) точно описывать язык, но в параграфе 14.3.3 «Аргумент шаблона шаблона» не упоминаются какие-либо ограничения на правила грамматики в этом контексте.

Кто-нибудь может принять или опровергнуть мои утверждения:

  1. Аргумент шаблона шаблона может быть ТОЛЬКО идентификатором, возможно, уточненным.
  2. Если пункт один верен, это определенно стоит упомянуть в стандарте.

person Kirill Kobelev    schedule 16.06.2012    source источник


Ответы (1)


14.3 [temp.arg] p1

"Существует три формы аргумента-шаблона, соответствующие трем формам параметра-шаблона: тип, нетип и шаблон. Тип и форма каждого аргумент-шаблона, указанный в идентификаторе-шаблона, должен соответствовать типу и форме, указанным для соответствующего параметра, объявленного шаблоном в его списке-параметров-шаблона.

Аргумент ~Helper не имеет правильного типа для параметра шаблона шаблона template<typename> class T, это не шаблон класса.

14.3.3 [temp.arg.template] p1

аргумент-шаблона для шаблона параметр-шаблона должен быть именем шаблона класса, выраженным как выражение-идентификатора.

~Helper не является именем шаблона класса.

Это довольно четко исключает ваши примеры.

person Jonathan Wakely    schedule 16.06.2012
comment
Я ожидал увидеть слова о форме нетерминала. Они использовали язык более высокого уровня: должно быть имя шаблона класса. Это также приемлемо. Виноват. В моем варианте грамматики C++ в этой ситуации я использую более строгий нетерминал. - person Kirill Kobelev; 20.06.2012
comment
@KirillKobelev, см. Приложение A [gram], параграф 1: Это краткое изложение синтаксиса C++ предназначено для облегчения понимания. Это не точное определение языка. В частности, описанная здесь грамматика допускает надмножество допустимых конструкций C++. Необходимо учитывать нормативную формулировку, а также правила грамматики. - person Jonathan Wakely; 20.06.2012
comment
Я упоминал об этом в начальном посте: грамматика не (и не должна) точно описывать язык (кстати). - person Kirill Kobelev; 20.06.2012