2016-04-15 9 views
1

タイプTo(ToとFromは列挙型)をキャストする関数が必要ですが、列挙型E1はE2にのみキャストできます。ユーザーが試行するとエラーが発生する必要があります例えばE1からE3をキャストする。C++の列挙型の特定のペアを

template<typename From, typename To> 
static To map(From f){ 
    return static_cast<To>(f); 
} 

どうすればいいですか? ありがとうございました!

+2

テンプレート専用化 –

+3

私に例を挙げてもらえますか? –

答えて

2

一つの可能​​な解決策:static_assert

template<typename From, typename To> 
static To map(From f) { 
    static_assert(!(std::is_same<From, E1>::value && std::is_same<To, E3>::value), 
        "cannot cast from E1 to E3"); 

    return static_cast<To>(f); 
} 

auto main() -> int { 
    E1 a; 
    const auto b = map<E1, E2>(a); // compiles 
    const auto c = map<E1, E3>(a); // won't compile 

    return 0; 
} 
+0

あなたのソリューションは面白いですが、static_assertはコンパイル時に評価され、実行時にはFromとToが評価されます –

+0

' - >'はどうなっていますか?これは現在C++の一部ですか?ああ、私は参照してください、メインはラムダ関数ですか?クール! – smac89

+0

Ionutはい、正しい。関数を呼び出すコードはどのように見えますか? @ Smac89はい、このようにmain(...)を宣言することができます:) – CppChris

1

テンプレートの特殊化によって、さまざまなタイプの作業方法を指定できます。以下の例を見てください。 map()機能はタイプE1と呼ばれる

template<typename To, typename From> 
To map(From f){ 
    return static_cast<To>(f); 
} 

template<> 
E2 map(E1 f){ 
    return static_cast<E2>(f); 
} 

次いで、特殊テンプレート関数ではなく、通常のテンプレート関数を実行します。しかし、タイプE1以外の通常のテンプレート関数が呼び出されます。

これにより、ユーザはE1からE2にのみキャストします。あなたが例外を投げたい場合、またはassertあなたの希望として定義を変更してください。

0

あなたはテンプレートの特殊化を使用する必要があります。また、Toテンプレートパラメータを最初のテンプレート引数に移動し、戻り値の型になるので、コンパイラはそれを推論できません。

まず、主なテンプレート関数を作成し、それを実装提供されていません。あなたのよう

template<> 
E2 map(E1 from) 
{ 
    return static_cast<E2>(from); 
} 

」:意味作るマッピングのための特殊化を行う、今

template<typename To, typename From> 
To map(From from); 

をあなたがそうでないものを呼び出そうとすると、あなたはエラーを起こすだろうと思うマッピングのための専門化を提供しました。例えば、VS2012であなたが行う場合:

E3 value = map<E3>(e1_value); 

マッピングのための実装がないとしてあなたは「unresovled外部シンボル」エラーが発生します。

0

以下は、Conceptsを使用したソリューションです。私の知る限りではまだ実験的なgcc6のコンセプトしか実装されていません。

GCC 6.0の実験バージョンでコンパイルさ
prog.cc: In function 'int main()': 
prog.cc:23:19: error: cannot call function 'To map(From) requires predicate(!((Same<From, E1>) && (Same<To, E3>))) [with From = E1; To = E3]' 
    map<E1, E3>(e1); 
       ^
prog.cc:10:11: note: constraints not satisfied 
static To map(From f) 
      ^~~ 

http://melpon.org/wandbox/permlink/mEG3Rl5jaMXj0GVg

$ G ++ prog.cc -Wall -Wextra -Iは/ usr

#include <type_traits> 

enum E1{}; 
enum E2{}; 
enum E3{}; 

template <class T, class U> concept bool Same = std::is_same<T,U>::value; 

template<typename From, typename To> 
static To map(From f) 
requires !(Same<From, E1> && Same<To, E3>) 
{ 
    return static_cast<To>(f); 
} 

int main() 
{ 
    E1 e1; 
    E2 e2; 
    E3 e3; 

    map<E1, E2>(e1); // Ok 
    map<E1, E3>(e1); // Compile Error ! 
} 

は、以下のようなエラーが表示されます/local/boost-1.60.0/include -std = gnu ++ 1z "-fconcepts"