Аргументы шаблона non type
$14.3.2 - "... Аргумент шаблона для непигового шаблона-шаблона без шаблона должен быть одним из:
... постоянное выражение (5.19), которое обозначает адрес объекта со статической продолжительностью хранения и внешней или внутренней привязки или функцией с внешней или внутренней связью..."
В приведенном ниже коде я не понимаю, почему "name2" и "name3" не разрешены как аргументы шаблона non type. Я использую gcc 4.7.2 в Windows.
Оба "name2" и "name3" являются именами массива и, следовательно, являются постоянными выражениями. Дальше 'name2' имеет внутреннюю связь, а 'name3' имеет как статическую, так и внутреннюю связь.
template<char const *p> void f()
{
}
char name1[] = "Hi";
static char name2[]= "Hi";
const static char name3[]= "Hi";
char *name4 = "Hi";
int main()
{
f<name1>();
f<name2>();
f<name3>();
f<name4>();
}
Ответы
Ответ 1
Как правильно предположил @Nawaz, это ошибка реализации, а не эзотерический угол стандарта.
В частности, gcc, похоже, имеет проблемы с ним. Запрет последнего name4
, который противоречит стандарту, остальная часть его компилируется с помощью clang
Ответ 2
Я думаю, что проблема заключается в том, что используемое вами выражение не является на самом деле указателями, а массивами, а распад указателя работает только для name1
. Скорее всего, это ошибка компилятора, как это было сказано в примечании @KonradRudolph, в разделе разрешен раздел 14.3.2 стандарта С++ 11, и между name1
, name2
и name3
нет ничего существенного,.
В качестве обходного пути следующее компиляция с GCC 4.7.2 с помощью -std=c++11
:
template<char const *p> void f()
{
}
char name1[] = "Hi";
static char name2[]= "Hi";
const static char name3[]= "Hi";
int main()
{
f<(char const*)&name1>();
f<(char const*)&name2>();
f<(char const*)&name3>();
}
В режиме С++ 98 он не компилируется, потому что результат каста никогда не является постоянным выражением, а в С++ 11 он может быть.