10

大規模なプログラムの特性クラスの一部として、含まれているクラス テンプレートのインスタンス化に使用された型に応じて異なる値を持つ可能性のある静的クラス変数を作成しようとしました。

関連するコードを単純化して、私が話していることの必要最小限の例を作成しました。

#include <iostream>
#include <string>
#include <type_traits>

template <class T, class Enable = void>
struct Foo;

template <class T>
struct Foo<T,
    typename std::enable_if<std::is_integral<T>::value>::type
>
{
    static std::string message;
};

template <class T>
struct Foo<T,
    typename std::enable_if<std::is_floating_point<T>::value>::type
>
{
    static std::string message;
};

template <class T, class Enable>
std::string Foo<T, Enable>::message;

GCC 4.6 では、これによりコンパイラ エラーが発生します: template definition of non-template ‘std::string Foo<T, Enable>::message. この問題は、最後の 2 行で静的変数を定義しているだけで発生しますstd::string Foo<T, Enable>::message

なぜこれが起こっているのか混乱しています。最後の 2 行を省略すると、コンパイラ エラーはなくなります (もちろん、リンカー エラーが発生します)。これは GCC のコンパイラ エラーですか?

4

1 に答える 1

10

これは、テンプレート パラメーターが部分的な特殊化と一致する場合にのみ機能します。

template <class T>
std::string Foo<T,
    typename std::enable_if<std::is_integral<T>::value>::type
>::message;

template <class T>
std::string Foo<T,
    typename std::enable_if<std::is_floating_point<T>::value>::type
>::message;

これは、C++03 標準のセクション 14.5.4.3 で指定されています。部分的な特殊化は新しいテンプレートであり、外部で定義されたメンバーのテンプレート パラメーターはクラス定義のテンプレート パラメーターと一致する必要があるため、メンバーが使用するテンプレートを認識できます。

あなたの例では、ルールは、整数または浮動小数点ではない型のメッセージ メンバーの定義を回避します。

于 2012-04-09T13:42:29.723 に答える