1

依存関係が示されている次のコードがコンパイルされない理由を理解するのに苦労しているので、修正に役立てていただければ幸いです。

main.cpp

#include <cstdlib>
#include <iostream>

#include "Foo.h"
#include "Bar.h"

int main()
{
    Foo<Bar> f1;        // ERROR
    Foo<Bar,true> f2;   // works
    return EXIT_SUCCESS;
}

Foo.h

template<typename T, bool S = T::HAS_NATIVE_SUPPORT>
struct Foo
{
};

Bar.h

struct Bar
{
    static const bool HAS_NATIVE_SUPPORT;
};

Bar.cpp

#include "Bar.h"
const bool Bar::HAS_NATIVE_SUPPORT = true;

VisualStudio2008のコマンドプロンプトで次のエラーが発生します

cl main.cpp Bar.cpp
main.cpp(12) : error C2975: 'S' : invalid template argument for 'Foo', expected compile-time constant expression
        c:\tmp\c++tests\so\Foo.h(1) : see declaration of 'S'

g ++(GCC)4.5.3では、次のエラーメッセージが表示されます。

$ g++ main.cpp Bar.cpp
main.cpp: In function ‘int main()’:
main.cpp:12:9: error: ‘Bar::HAS_NATIVE_SUPPORT’ is not a valid template argument for type ‘bool’ because it is a non-constant expression
main.cpp:12:12: error: invalid type in declaration before ‘;’ token
4

2 に答える 2

3

テンプレートパラメータの値はコンパイル時に認識されている必要がありますが、別のソースファイルでメンバーの値を初期化することにより、コンパイラは必要なときに値が何であるかを確認できません。

コンパイル時定数として使用できるようにするには、クラスの静的メンバーを初期化する必要があります。

struct Bar
{
    static const bool HAS_NATIVE_SUPPORT = true;
};
于 2012-07-09T14:28:00.133 に答える
1

静的メンバー変数は、クラス本体内でも初期化されている場合にのみコンパイル時定数になります。

したがって、そこで初期化するか、次のいずれかのバリアントを使用します。

template <bool B>
void Y () {}

struct X {
    enum { foo = true };
    enum : bool { bar = true };
    static const bool frob = true;
    static constexpr bool frobnicate = true;
};

int main () {
    Y<X::foo>();
    Y<X::bar>();
    Y<X::frob>();
    Y<X::frobnicate>();
}
于 2012-07-09T14:44:04.863 に答える