19

持つ:

struct Value
{
    template<class T>
    static constexpr T value{0};
};

(0) イデオン

template<typename TValue>
struct Something
{
    void x()
    {
        static_assert(TValue::template value<int> == 0, "");
    }
};

int main() { Something<Value>{}.x(); return 0; } 
  • clang++ 3.6 ではコンパイルできません。

    エラー: テンプレート引数リストがないと、変数テンプレート '値' を参照できません

  • g++ 5.2 ではコンパイルできません。

    エラー: 'template constexpr const T Value::value' は関数テンプレートではありません


(1) イデオン

clang++ と g++ の両方でコンパイルできます。

struct Something
{
    void x()
    {
        static_assert(Value::template value<int> == 0, "");
    }
};

int main() { Something{}.x(); return 0; } 

(0)がコンパイルに失敗するのはなぜですか?

テンプレート パラメーター (この場合は ) を介して変数テンプレートにアクセスすると、問題が発生するようですTValue。キーワードの型エイリアスを定義するTValueか、typenameキーワードを使用しても問題は解決しません。

何が起きてる?

4

2 に答える 2

10

これは、変数テンプレートを従属名として扱う際の gcc および clang のバグであることは間違いありません。gcc 67248clang 24473を提出しました。

現時点での回避策として、両方のコンパイラが変数テンプレートの古い方法をサポートしています。つまり、以下を追加した場合です。

struct Value
{
    template<class T>
    static constexpr T value = 0;

    template <typename T>
    struct variable_template_ish {
        static constexpr T value = Value::value<T>;
    };
};

次に、以下がコンパイルされます。

template<typename TValue>
struct Something
{
    void foo() {
        static_assert(TValue::template variable_template_ish<int>::value == 0, "");
    }
};

int main() { 
    Something<Value>{}.foo();
}
于 2015-08-17T12:55:00.703 に答える
0

以前、c++ でテンプレート クラス ヘッダー ファイルを作成するときに頭を悩ませていました。

static constexpr T value{0};の実装が宣言と同じヘッダー ファイルにあることを確認してください。

于 2015-08-17T12:57:35.200 に答える