2016-08-26 2 views
3

を有効に私は必要に応じてテンプレート引数typename IDENTIFICATION_GROUPとして「識別グループタイプ」を保持する「パラメータ」クラスがあります。下記のように、クラスの型をパラメータ・クラスをinstantinating間SFINAE:クラスコンストラクタ

struct ConstrainedParameterIdentification_None {}; 

template<typename UNIT_TYPE, typename DATA_TYPE = double, typename IDENTIFICATION_GROUP = ConstrainedParameterIdentification_None> 
class Parameter 
{ 
    /* Constructor - the only method taking care about valid IDENTIFICATION_GROUP */ 
    template<typename = std::enable_if<!std::is_same<IDENTIFICATION_GROUP, ConstrainedParameterIdentification_None>::value>> 
    Parameter(const typename IDENTIFICATION_GROUP::IDType ID) 
    { /* ... */ } 
}; 

あります(interresting部分がusing IDType = int;です)使用:

struct SampleIdentificationGroup 
{ 
    using IDType = int; 
    /* ... */ 
}; 

私はこのようなパラメータをinstantianteない限り:

Parameter<si::length, double, SampleIdentificationGroup> Param; 

すべて正常に動作しています。

しかし、一度デフォルト値IDENTIFICATION_GROUP - ConstrainedParameterIdentification_Noneを使用したいのであれば、私のトラブルが発生します。私の最初の試みはIDTypeConstrainedParameterIdentification_Noneにも定義することでしたが、副作用のために解決策ではありません。したがって、IDENTIFICATION_GROUP「内部(typedefs ...)」を使用してパラメータメンバメソッドを有効/無効にしたいと思います。だから私は私のコンストラクタ(唯一の方法は、世話をする程度IDENTIFICATION_GROUP無効/有効にするSFINAEを適用しようとしました

IDENTIFICATION_GROUP場合は「内部の)人間の言語で

template<typename = std::enable_if<!std::is_same<IDENTIFICATION_GROUP, ConstrainedParameterIdentification_None>::value>> 
Parameter(const typename IDENTIFICATION_GROUP::IDType ID) 
{ /* ... */ } 

私が到達しようとしている何があります」 ConstrainedParameterIdentification_Noneであり、方法全体を除外する。 。

しかし、GCCはない定義されているタイプのidtype文句:?右、

error: no type named ‘IDType’ in ‘struct Base::ConstrainedParameterIdentification_None’ 
    Parameter(const typename IDENTIFICATION_GROUP::IDType ID) 

しかし、原因SFINAEに、Parameter(const typename IDENTIFICATION_GROUP::IDType ID)がビルドから除外されなければならないので、このような文句を言う、なぜ私が何をしているのですか?間違った?助けて喜んで誰にも事前に

多くのおかげで...

乾杯マーティン

答えて

2

私はそう、あなたは単にあなたがC++ 14を使用することができた場合は、std::enable_it_tはannoing typenameとannoing ::typeを避ける必要があります

template <typename IG = IDENTIFICATION_GROUP> 
    Parameter (typename std::enable_if<false == std::is_same<IG, ConstrainedParameterIdentification_None>::value, typename IG::IDType>::type const ID) 
{ /* ... */ } 

次のようにあなたのコンストラクタを書くことができ

template <typename IG = IDENTIFICATION_GROUP> 
    Parameter (std::enable_if_t<false == std::is_same<IG, ConstrainedParameterIdentification_None>::value, typename IG::IDType> const ID) 
{ /* ... */ } 
+0

と仮定しますしたがって、テンプレートパラメータとして存在しない型を渡すことは、SFINAEにとって依然として有効なケースです。知っておいてよかった! – Dmitry

1

問題は股関節です存在しないタイプをstd::enable_ifに渡そうとしています。これを解決するには、簡単にenable_ifの独自のバージョンを考え出すことができます。

template <typename IDENTIFICATION_GROUP = ConstrainedParameterIdentification_None> struct my_enable_if { 
    using type = typename IDENTIFICATION_GROUP::IDType; 
}; 
template <> struct my_enable_if<ConstrainedParameterIdentification_None> { 

}; 

template<typename IDENTIFICATION_GROUP = ConstrainedParameterIdentification_None> class Parameter { 
    public: 
     template <typename Unused = IDENTIFICATION_GROUP> 
     Parameter(typename my_enable_if<Unused>::type ID) { } 
     Parameter() { } 

}; 

ダミーUnusedテンプレートパラメータSFINAEが機能するために(問題の方法は、少なくとも1つのテンプレートパラメータに依存しなければなりません)が必要です。