аргументы не типа шаблона
$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>();
}
2 ответов
Как правильно догадался @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 mode он не компилируется, потому что результат приведения никогда не является постоянным выражением, в то время как в C++11 это может быть.