2016-07-18 4 views
4

タイプがいくつかの条件に依存する変数を定義したいと思います。私はこのような何かしたい:typedefとともにenable_ifを使用できますか?

typedef typename enable_if<cond, int>::type Type; 
typedef typename enable_if<!cond, double>::type Type; 

をしかしconpilerは、私はタイプを再定義と言います。

どうすればいいですか?

答えて

7

あなたが使用する必要がありますstd::conditional

#include <type_traits> 

// c++11: 
typedef typename std::conditional<cond, int, double>::type Type; 

// c++14: 
typedef std::conditional_t<cond, int, double> Type; 

は、C++ 11以降あなたは(私の意見では少しクリーナー)タイプとテンプレートエイリアスのためusingキーワードを使用できることに注意してください。

// c++11 
using Type = typename std::conditional<cond, int, double>::type; 

// c++14 
using Type = std::conditional_t<cond, int, double>; 
9

typedefと一緒にenable_ifを使用できますか?

いいえできません。条件がfalseの場合、std::enable_ifは型を未定義のままにします。条件が真である場合のみ、メンバーtypeが定義されています。

template< bool B, class T = void > 
struct enable_if; 

Btrue場合、std::enable_ifTに等しいパブリックメンバのtypedef型を有します。それ以外の場合は、メンバーtypedefはありません。

typedefが正しく機能するためには、条件がtrueの場合とfalseの場合の両方の型が必要です。 SFINAEに関連するシナリオを支援するためにenable_ifが実装されています。

それでは

どのように私はこれを行うことができますか?

std::conditionalを使用してください。条件には、truefalseの両方の結果のメンバtypedef(type)が含まれます。

template< bool B, class T, class F > 
struct conditional; 

Bがコンパイル時にtrueある場合、又はFとしてBfalseであればTとして定義されるメンバーのtypedef型を提供します。

したがって、次のことで十分です。

typedef typename std::conditional<cond, int, double>::type Type; 

またはそれ以上の短縮;

using Type = std::conditional_t<cond, int, double>; 
+0

SFINAEをtypedefで使用することは実際には法的ではありません。 'テンプレートクラスC {typedef std :: enable_if ::値、タイプ> }; '? – Flexo

+0

実際はありません。 https://godbolt.org/g/2YT04Q。私はテンプレートの控除の直後の文脈の外でそれを実際に見たこともありませんでした。この問題は、条件がfalseの場合に起こります。typedefには、エイリアスの型がありません。 SFINAEは、関数テンプレートのオーバーロードを解決するために使用されます。http://en.cppreference.com/w/cpp/language/sfinae – Niall

関連する問題