2

次のプログラムは正常に動作:SFINAE、Constraints、またはConceptsを使用した特殊化の制限?

struct M; // forward declare so compiler will recognize this type 
struct N; 

template< typename J > struct B { template< typename U > void Func1(); }; 

template<> template<> void B<M>::Func1<M>() {} 
template<> template<> void B<N>::Func1<N>() {} 
template<> template<> void B<M>::Func1<N>() {} // illegal specialization for this app 

template< typename J > struct C { template< typename U > void Func2(); }; 

template<> template<> void C<M>::Func2<M>() {} 
template<> template<> void C<N>::Func2<N>() {} 

template< typename G > struct H { G g; }; 

int main() 
{ 
    H< B<M> > hbm; 
    hbm.g.Func1<M>(); // ok 
    hbm.g.Func1<N>(); // compiles and runs, but uses a semantically illegal specialization for this app 

    H< B<N> > hbn; 
    hbn.g.Func1<N>(); // ok 

    H< C<M> > hcm; 
    hcm.g.Func2<M>(); // ok 

    H< C<N> > hcn; 
    hcn.g.Func2<N>(); // ok 

    return 0; 
} 

構造体BおよびCは、コンパイル時に明示的に宣言し、アプリに意味をなすもののみ特化が許可されることをすることが重要です。

しかし、私の川下の開発者(数日!)は意味的に意味をなさない構文的に正しいパターンを作成することができます。具体的には、アプリケーションはクラスと関数の型が等しい型の使用方法しか知りません。残りは無意味です。

これは、SFINAE、Constraints、またはConceptsのような新しいC++ 17 +機能のケースのようです。私はこれらについて読んでいますが、私はまだその選択をする判決はありません。 Alternativesのcppreferenceでは、コンパイラが可能ならばSFINAEの代わりにConceptsを提案します(私はVS2015を使用します)。

typename Jをtypename Uと同じにするにはどうすればよいでしょうか?

+1

SFINAEはC++に新しいものではありません。制約は事実上概念と同じです。 –

+0

概念はC++ 17の一部ではないことに気付きましたか? – SergeyA

+0

'typename = std :: enable_if_t {}>'テンプレートのパラメータリストでは、 –

答えて

2

あなたはenable_ifを使用することができます概念を

template< typename J > struct B {  
    template<typename U> 
    typename std::enable_if<std::is_same<U, J>::value, void>::type 
    Func1(); 
}; 

http://coliru.stacked-crooked.com/a/efb499cf654f0f25

(ない標準に近い()将来に?)同じ溶液は、上記のように、以下のようになります。

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

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

template< typename J > struct B { 
    template< typename U > 
    requires Same<J, U>  
    void Func1(); 
}; 
+0

いいえ、あなたはこの方法ではありません。デフォルトのテンプレート引数は関数シグネチャの一部ではありません。 – SergeyA

+0

これは、[マキアベリ対マーフィー](http:// coliru。stack-crooked.com/a/1c4b584653b49af2)の状況、それが何かの助けであるかどうかを誰にでも判断させることができます。 –

+0

@SergeyAここではJテンプレートパラメータを "コピー"する必要があります。template marcinj

関連する問題