$ 14.3.2 — «… Аргумент шаблона для нетипового, не шаблонного параметра шаблона должен быть одним из:
…константное выражение (5.19), которое обозначает адрес объекта со статической продолжительностью хранения и внешний или внутренний связь или функция с внешней или внутренней связью … »
В коде, показанном ниже, я не понимаю, почему «name2» и «name3» не допускаются в качестве аргументов шаблонов не-типа. Я использую 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>();
}
Как правильно догадался @Nawaz, это ошибка реализации, а не эзотерический угол стандарта.
В частности, у gcc, похоже, проблемы с этим. За исключением последнего name4
что противоречит стандарту, остальное компилируется нормально лязг
Я думаю, что проблема в том, что выражение, которое вы используете, на самом деле не указатели, а массивы, и затухание указателя работает только для name1
, Скорее всего, это ошибка компилятора, как любезно @KonradRudolph указал в комментарии, раздел 14.3.2 стандарта C ++ 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>();
}
В режиме C ++ 98 он не компилируется, потому что результат приведения никогда не является константным выражением, в то время как в C ++ 11 это может быть.