タイプTo(ToとFromは列挙型)をキャストする関数が必要ですが、列挙型E1はE2にのみキャストできます。ユーザーが試行するとエラーが発生する必要があります例えばE1からE3をキャストする。C++の列挙型の特定のペアを
template<typename From, typename To>
static To map(From f){
return static_cast<To>(f);
}
どうすればいいですか? ありがとうございました!
タイプTo(ToとFromは列挙型)をキャストする関数が必要ですが、列挙型E1はE2にのみキャストできます。ユーザーが試行するとエラーが発生する必要があります例えばE1からE3をキャストする。C++の列挙型の特定のペアを
template<typename From, typename To>
static To map(From f){
return static_cast<To>(f);
}
どうすればいいですか? ありがとうございました!
一つの可能な解決策: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;
}
テンプレートの特殊化によって、さまざまなタイプの作業方法を指定できます。以下の例を見てください。 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
あなたの希望として定義を変更してください。
あなたはテンプレートの特殊化を使用する必要があります。また、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外部シンボル」エラーが発生します。
以下は、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"
テンプレート専用化 –
私に例を挙げてもらえますか? –