#cpp
Почему нельзя использовать в аргументах шаблонов сущности с внутренней компоновкой? templateclass Template { ... }; Template<"literal"> T; // Ошибка! Нельзя использовать и глобальный указатель: template class Template { ... }; char const *s = "Literal"; Template T; // Ошибка! Интересуют физические причины этих ограничений, а не правила, как можно а как нельзя.
Ответы
Ответ 1
В первом случае использование невозможно, так как даже одинаковые строковые литералы не обязаны иметь одинаковые адреса в программе. Т.е. Template<"literal"> мог бы получать разный аргумент шаблона в зависимости от контекста (если бы это было разрешено). Более того, в черновике стандарта N4687 использование строковых литералов явно запрещено в шаблонах 17.3.2/2: For a non-type template-parameter of reference or pointer type, the value of the constant expression shall not refer to (or for a pointer type, shall not be the address of): a subobject (4.5), a temporary object (15.2), a string literal (5.13.5), Это касается как непосредственного указания литерала, так и переменной типа char const * (см. далее). Во втором случае ошибка из-за использования переменной, а не адреса, фиксированного на момент компиляции. Например, gcc даёт следующую ошибку: error: 's' is not a valid template argument because 's' is a variable, not the address of a variable Чтобы всё же использовать шаблон, можно заменить указатель массивом: const char s[] = "literal"; TemplateT; Внутренняя или внешняя компоновка (linkage) будет - не важно по современным меркам, главное, чтобы она была, т.е. нельзя, например, использовать локальные объекты: templateclass Template { }; const char i[] = "literal"; // internal linkage char e[] = "literal"; // external linkage int main() { char n1[] = "literal"; // no linkage const char n2[] = "literal"; // no linkage constexpr char n3[] = "literal"; // no linkage Template Ti; // ok Template Te; // ok Template Tn1; // error Template Tn2; // error Template Tn3; // error }
Комментариев нет:
Отправить комментарий