2017-03-04 6 views
0

私はいくつかのメンバーを持つenumクラスを持っています。列挙型の目的は、実行時にプリミティブ型(int、long、floatなど)をエンコードすることで、この情報をデータベースなどに格納することが可能です。同時に、プリミティブ型で動作するようにテンプレート化された多くのクラスも存在します。C++のenum値からテンプレート引数へのマップ

問題:このようなテンプレート化されたクラスから、定数ではないenum値を指定してオブジェクトを作成したいとします。これは、列挙型の値に長いスイッチを作成する(または、回答の中で提案されているマップと本質的に同じである)よりも、よりクリーンでスケーラビリティのある方法で可能でしょうか?Dynamic mapping of enum value (int) to type?ここで

は、私は、テンプレート型推論は仕事ができることを期待しようとしてきたが、それは(:http://rextester.com/VSXR46052例えばここでチェックすることができます):コンパイルに失敗した何か

#include <iostream> 

enum class Enum { 
    Int, 
    Long 
}; 

template<Enum T> 
struct EnumToPrimitiveType; 

template<> 
struct EnumToPrimitiveType<Enum::Int> { 
    using type = int; 
}; 

template<> 
struct EnumToPrimitiveType<Enum::Long> { 
    using type = long; 
}; 

template<typename T> 
class TemplatedClass 
{ 
public: 
    TemplatedClass(T init): init{init} {} 
    void printSize() { std::cout << sizeof(init) << std::endl; } 
private: 
    T init; 
}; 

template<Enum T> 
auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type> 
{ 
    TemplatedClass<EnumToPrimitiveType<T>::type> ret(5); 
    return ret; 
} 

int main() 
{ 
    Enum value{Enum::Int}; 
    auto tmp = makeTemplatedClass(value); 
    tmp.printSize(); 
} 

コンパイルエラー:

source_file.cpp:36:27: error: expected ‘)’ before ‘enumValue’ 
auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type> 
         ^
source_file.cpp:36:6: warning: variable templates only available with -std=c++14 or -std=gnu++14 
auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type> 
    ^
source_file.cpp:36:38: error: expected ‘;’ before ‘->’ token 
auto makeTemplatedClass(T enumValue) -> TemplatedClass<EnumToPrimitiveType<T>::type> 
            ^
source_file.cpp: In function ‘int main()’: 
source_file.cpp:44:16: error: ‘A’ is not a member of ‘Enum’ 
    Enum value{Enum::A}; 
       ^
source_file.cpp:45:34: error: missing template arguments before ‘(’ token 
    auto tmp = makeTemplatedClass(value); 
           ^
私が見

答えて

2

問題:あなたが使用することはできません

  1. template<Enum T> auto makeTemplatedClass(T enumValue)Tはタイプではないのでちょうどtemplate<Enum T> auto makeTemplatedClass()を使用し、関数を別々に呼び出す必要があります。

  2. の代わりにTemplatedClass<typenmae EnumToPrimitiveType<T>::type>を使用する必要があります。 typeは依存型であるため、これが必要です。

  3. constまたはconstexpr以外の場合は、valueをテンプレートパラメータとして使用できません。

次のプログラムは、デスクトップ上でコンパイルしてビルドします。

#include <iostream> 

enum class Enum { 
    Int, 
    Long 
}; 

template<Enum T> 
struct EnumToPrimitiveType; 

template<> 
struct EnumToPrimitiveType<Enum::Int> { 
    using type = int; 
}; 

template<> 
struct EnumToPrimitiveType<Enum::Long> { 
    using type = long; 
}; 

template<typename T> 
class TemplatedClass 
{ 
public: 
    TemplatedClass(T init): init{init} {} 
    void printSize() { std::cout << sizeof(init) << std::endl; } 
private: 
    T init; 
}; 

template<Enum T> 
auto makeTemplatedClass() -> TemplatedClass<typename EnumToPrimitiveType<T>::type> 
{ 
    TemplatedClass<typename EnumToPrimitiveType<T>::type> ret(5); 
    return ret; 
} 

int main() 
{ 
    Enum const value{Enum::Int}; 
    auto tmp = makeTemplatedClass<value>(); 
    tmp.printSize(); 
} 
+0

ありがとうございます。ありがとうございます、あなたの修正は実際には動作しますが、残念なことに3の解決策ではありません。必須の要件は 'value'は' const'/'constexpr'ではないということです。私の希望は 'template auto makeTemplatedClass(T enumValue)'でテンプレートパラメータとして 'value'を指定せずにこの関数を呼び出すことができ、自動的に推測されるようになりましたが、これはうまくいきません。 – misev

+0

@misev、 'value'を' const'や 'constexpr'以外のテンプレートパラメータとして使うことはできませんので、描画ボードに戻って値を扱うことができる解決法を考えてください実行時にしか知ることができません。あなたが本当にやろうとしていることが私にはっきりしないので、今は何も示唆できません。 –

関連する問題