В обсуждении другого вопроса мне был приведен пример, где, по-видимому, связь идентификатора повлияла на его удобство использования в постоянном выражении:
extern char const a[] = "Alpha";
char constexpr b[] = "Beta";
char const g[] = "Gamma";
template <const char *> void foo() {}
auto main()
-> int
{
foo<a>(); // Compiles
foo<b>(); // Compiles
foo<g>(); // Doesn't compile
}
Ошибка последнего (с GCC):
test.cc: In function 'int main()':
test.cc:12:13: error: the value of 'g' is not usable in a constant expression
foo<g>(); // Doesn't compile
^
test.cc:3:16: note: 'g' was not declared 'constexpr'
char const g[] = "Gamma";
^
Возможно, я пропустил значение примера в предыдущем обсуждении, потому что я считал, что это не могло быть просто связью, которая отличалась foo<a>
от foo<g>
. Однако я начал сомневаться в этой позиции.
- Это действительно связка, или это какой-то другой атрибут, предоставленный
extern
, который позволяетfoo<a>()
? - В чем обоснование разрешения
foo<a>()
, но неfoo<g>()
? В частности, если это связано с привязкой, почему внутренняя связь приводит к тому, что переменная не может использоваться в качестве постоянного выражения, когда можно использовать одну и ту же переменную, объявленную какextern
? - Было высказано мнение о том, что вопрос о том, чтобы символ был видимым (или нет) компоновщику, имеет значение здесь. Мне кажется, что вариант
foo<b>
по-прежнему разрешен даже при добавленииstatic
, это опровергает - или я ошибаюсь? - (Разница между
foo<b>()
иfoo<g>()
адекватно покрывается другими вопросами, я думаю).