14.3.2 テンプレート非型引数 [temp.arg.nontype] (C++03 標準) から、すべての利益のために標準が述べていることから始めましょう。
1 非型、非テンプレートのテンプレート パラメータのテンプレート引数は、次のいずれかになります。
— 整数型または列挙型の整数定数式; また
— 非型テンプレートパラメータの名前; また
—関数テンプレートと関数テンプレート ID を含むが非静的クラス メンバを除く、外部リンケージを持つオブジェクトまたは関数のアドレス。名前が関数または配列を参照する場合、& はオプションです。対応するテンプレート パラメータが参照の場合。また
— 5.3.1 で説明されているように表現されたメンバーへのポインター。
関連する部分を強調します。
さらに、パラグラフ 5 には、許可されている変換がリストされており、そのうちの 1 つは配列からポインターへの減衰です。char*
パラグラフ 2 は、OP と同様の使用法を示すメモですらあります。
残っているのは、外部リンケージを使用してエラーなしでヘッダーにオブジェクトを含める方法だけです。通常の方法は、ヘッダーでの宣言と、1 つの TU での 1 つの定義のみです。
// 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 の私のコピーはまだそれをサポートしていません。) 文字列リテラルは、テンプレートの引数として表示することを不可解にもまだ禁止されています。