2012-01-27 11 views
1

私はテンプレート引数として渡したいクラスのメンバーとしてenum値を持っていますか?コンパイラはメンバが定数式で使用できないと不平を言う。この作品を手に入れる魔法はありますか?変数からテンプレートパラメータを設定する方法はありますか?

私の現在の解決策はswitch-case文ですが、私の元のコードETypeには200件近くのエントリがあります。だから私の最初のアイデアは型に列挙型の値をマッピングするためのtype_traitsを書くことでした。ここで

は私の問題の例(もideone.com上)(問題がmain()の最後の行である)である:

#include <iostream> 

enum EType 
{ 
    eType_A, 
    eType_B, 
    eType_C 
}; 

struct Foo 
{ 
    Foo(EType eType) 
     : m_eType(eType) 
    { 
    } 

    EType m_eType; 
}; 

template <EType eType> 
struct Bar 
{ 
    static std::string const toString() 
    { 
     return "-"; 
    } 
}; 

template <> 
struct Bar<eType_A> 
{ 
    static std::string const toString() 
    { 
     return "A"; 
    } 
}; 

template <> 
struct Bar<eType_B> 
{ 
    static std::string const toString() 
    { 
     return "B"; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Bar<eType_A>::toString()=" << Bar<eType_A>::toString() << "\n"; 
    std::cout << "Bar<eType_B>::toString()=" << Bar<eType_B>::toString() << "\n"; 
    std::cout << "Bar<eType_C>::toString()=" << Bar<eType_C>::toString() << "\n"; 

    Foo stFooA(eType_A); 
    std::cout << "Bar<stFooA.m_eType>::toString()=" << Bar<stFooA.m_eType>::toString() << "\n"; // <--- here ist the problem 
} 

例これらのエラーを生成します。

prog.cpp: In function ‘int main(int, char**)’: 
prog.cpp:54: error: ‘stFooA’ cannot appear in a constant-expression 
prog.cpp:54: error: `.' cannot appear in a constant-expression 
prog.cpp:54: error: template argument 1 is invalid 

答えて

5

Bar に渡すテンプレート引数は、コンパイル時にはでなければなりません。 stFooA.m_eTypeが実行時に変更されるため、このエラーが発生するため、動作しません。

あなたの他の質問に答えるには、これを動作させるにはいくつかの魔法がありますか?おそらく多分 - m_eTypeの値をコンパイル時に知らせることが許されていますか?それはあなたがこのようなものに変更することができ、それがうまくいく問題に対して有効な制約だ場合:

// ... 
template <EType eType> 
struct Foo 
{ 
    Foo() 
    { 
    } 

    static const EType m_eType = eType; 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Bar<eType_A>::toString()=" << Bar<eType_A>::toString() << "\n"; 
    std::cout << "Bar<eType_B>::toString()=" << Bar<eType_B>::toString() << "\n"; 
    std::cout << "Bar<eType_C>::toString()=" << Bar<eType_C>::toString() << "\n"; 

    Foo<eType_A> stFooA; 
    std::cout << "Bar<stFooA.m_eType>::toString()=" 
       << Bar<Foo<eType_A>::m_eType>::toString() 
       << "\n"; // Foo<eType_A>::m_eType is known at compile-time so this works 
} 
+0

良い点として壊れて...それを恐れていたが、方法はありません'm_eType'をコンパイル時に認識させます。 – Lars

+0

@ Larsその場合、あなたは選択肢がありません - テンプレートはおそらくタスクのための適切なツールではないので、何らかの形で実行時に解決する必要があります。おそらくテンプレートの引数を 'toString'の通常の関数のパラメータに変えますか? – greatwolf

3

いいえ、テンプレートの展開はコンパイル時に行われます。プログラムがコンパイルされるときに値が分かっている場合にのみ機能します。

コンパイラは定数式も求めます。

+0

私が設計し... – Lars

関連する問題