11

$14.3.2 - "... 非型、非テンプレートのテンプレート パラメータのテンプレート引数は、次のいずれかになります。

...静的な保存期間と外部リンケージまたは内部リンケージを持つオブジェクト、または外部リンケージまたは内部リンケージを持つ関数のアドレスを指定する定数式 (5.19)..."

以下に示すコードでは、'name2' と 'name3' が非型テンプレート引数として許可されていない理由がわかりません。Windows で gcc 4.7.2 を使用しています。

「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>();
}
4

2 に答える 2

5

@Nawazが正しく推測したように、これは実装のバグであり、標準の難解なコーナーではありません。

具体的には、gcc に問題があるようです。name4標準に反する最後のものを除いて、残りはclangで正常にコンパイルされます

于 2013-01-07T10:07:02.537 に答える
3

問題は、使用する式が実際にはポインターではなく配列であり、ポインターの減衰が。に対してのみ機能することだと思いますname1。@KonradRudolphがコメントで指摘したように、これはコンパイラのバグである可能性が高いです。C++ 11標準のセクション14.3.2で許可されており、との間で本質的な違いはありませname1ん。name2name3

回避策として、以下を使用してGCC4.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モードでは、キャストの結果が定数式になることはないため、コンパイルされませんが、C++11ではコンパイルされる可能性があります。

于 2013-01-07T10:12:39.687 に答える