Давайте начнем с того, что Стандарт говорит для всеобщего блага, с 14.3.2 Типовые аргументы нетипичного типа [temp.arg.nontype] (Стандарт C ++ 03):
1 Шаблон-аргумент для нетипичного, не шаблонного шаблона-параметра
должен быть одним из:
- интегральная константа-выражение интеграла или
тип перечисления; или
- имя нетипового шаблона-параметра; или
- адрес объекта или функции с внешней связью , в том числе
шаблоны функций и идентификаторы шаблонов функций, но исключая нестатические
члены класса, выраженные как & id-выражение , где символ & является необязательным, если
имя относится к функции или массиву , или если соответствующая
параметр-шаблона является ссылкой; или
- указатель на член выражен
как описано в 5.3.1.
Акцент на шахте для соответствующих частей.
Кроме того, в параграфе 5 перечислены допустимые преобразования, и одним из них является затухание указателя массива в указатель. Параграф 2 - даже примечание, которое демонстрирует аналогичное использование char*
, как и у OP.
Осталось только получить объект в заголовке с внешней связью и без ошибок. Обычным способом является объявление в заголовке и одно-единственное определение в одном TU.
// In header
extern char EL[]; // array of unspecified size, an incomplete type
// extern char EL[3] is acceptable, too.
// In source
char EL[] = "el";
Обратите внимание, что static
не представляется возможным из-за требования, чтобы объект имел внешнюю связь. Неименованное пространство имен должно быть предпочтительным, если предполагается, что в TU должен быть отдельный объект.
// In header
// NOT RECOMMENDED! Be wary of ODR-violations with such constructs
// or simply only use these in source files
namespace {
// Recommend using const here, which in turn means using extern
// change non-type template parameter accordingly
extern const char EL[] = "el";
} // namespace
Для любопытных C ++ 0x ослабил требование, чтобы объект имел внешнюю связь, чтобы быть допустимым параметром. (Моя копия GCC пока не поддерживает это.) Строковые литералы необъяснимо все же запрещено отображать в качестве аргументов шаблона.