В приведенном ниже примере попытка использовать переменную ссылочного типа в качестве аргумента для параметра шаблона непигового типа (самого ссылочного типа). Clang, GCC и VС++ все это отвергают. Но почему? Я не могу найти ничего в стандарте, что делает его незаконным.
int obj = 42;
int& ref = obj;
template <int& param> class X {};
int main()
{
X<obj> x1; // OK
X<ref> x2; // error
}
CLang говорит:
source_file.cpp: 9: 7: ошибка: аргумент шаблона непигового типа ссылочного типа 'int &' не является объектом
Другие жалуются аналогичным образом.
Из стандарта (все кавычки из С++ 11; С++ 14 не имеет существенных изменений в соответствующих частях):
14.3.2/1 Аргумент шаблона для непигового шаблона-шаблона без шаблона должен быть одним из:
...
- постоянное выражение (5.19), которое обозначает адрес объекта со статической продолжительностью хранения и внешней или внутренней связью... выражается (игнорируя круглые скобки) как
&
id-expression, за исключением того, что&
... должны быть опущены, если соответствующий шаблон-параметр является ссылкой...
Теперь какое постоянное выражение:
5.19/2 Условное выражение является выражением основной константы, если оно не включает одно из следующих значений в качестве потенциально оцененного подвыражения (3.2)...
...
- id-выражение, которое ссылается на переменную или элемент данных ссылочного типа, если ссылка не имеет предыдущей инициализации, инициализированной константным выражением
...
Насколько я могу судить, ref
in X<ref>
- это id-выражение, которое ссылается на переменную ссылочного типа. Эта переменная имеет предыдущую инициализацию, инициализированную выражением obj
. Я считаю, что obj
является постоянным выражением, и в любом случае, если это не так, тогда X<obj>
тоже не должен компилироваться.
- Так что мне не хватает?
- Какое предложение в стандарте делает недействительным
X<ref>
, аX<obj>
является допустимым?