2017-04-22 3 views
2

テンプレートの引数に許容される値をいくつか受け入れるように関数テンプレートを制限するのは悪い方法ですか?C++で許容されるテンプレート引数を制限するのは悪い方法ですか?

例:

template<typename T> 
class Foo { 

typename std::enable_if<std::is_same<Bar, T>::value, void>::type 
    callFuncInBar() { 
     BarGetValue(); 
    } 


typename std::enable_if<std::is_same<FooBar, T>::value, void>::type 
    callFuncInFooBar() { 
     FooBarGetValue(); 
    } 

}; 

EDIT: 私の場合はこれです: 私はほとんど似ている2つの簡単な構造体AとBがあります。

struct A: public ICompress { 
    void compress() override { 
     next->compress(); 
    } 

    ICompress *next; 
}; 

struct B: public IDecompress { 
    void decompress() override { 
     next->decompress() 
    } 

    IDecompress *next; 
}; 

を私の意図は、そのテンプレートを作成することでしたコンプレッサまたはデコンプレッサとしてインスタンス化する必要があります。

template<typename T> 
struct codecomp: public T { 
    typename std::enable_if<std::is_base_of<ICompress, T>::value, void>::type 
    compress() { 
     next->compress(); 
    } 

typename std::enable_if<std::is_base_of<IDecompress , T>::value, void>::type 
    decompress() { 
     next->decompress(); 
    } 

    T *next; 
}; 
+1

C++ 17には[concepts](https://en.wikipedia.org/wiki/Concepts_(C% 2B%2B))。その前にインスタンス化を選択する唯一の可能性はSFINAE(あなたの質問のように)です。 –

+2

@HenriMenkeいいえ、C++ 17には概念がありません。 – cpplearner

+0

短い答え:いいえ。いくつかの型には意味をなさないが他の型には意味のないテンプレートがある場合、他の型に対してインスタンス化されないようにするのが理にかなっています。たとえば、テンプレート化されたケーパビリティが数値型に対してのみ意味がある場合は、数値以外の型に対してインスタンス化されないようにします。その制限を強制する方法は、悪いスタイルかもしれません。たとえば、型が "数値"であるかどうかをコンパイル時にチェックする方法を指定します。 – Peter

答えて

2

書かれているように、Fooがインスタンス化されると、コードはコンパイルに失敗します。 TのタイプがBarでない場合、Foo<T>のインスタンス化により、返されるタイプはFoo<T>::callFuncInBarになりますが、これは失敗します。同様に、TFooBarと同じでない場合、戻りタイプのインスタンス化はcallFuncInFooBarになりません。

私はこれがあなたの望むものではないと思います。

Foo<T>::callFuncInBarは、TBarの場合にのみ呼び出すことができます。これは通常、テンプレートの特殊化によって処理されます。をT = BarT = FooBarに特化し、プライマリテンプレートではcallFuncInBarcallFuncInFooBarのメンバー関数を宣言しないでください。これにより、あなたのスタイルに関する質問は完全に回避されます。 Fooはテンプレート引数でインスタンス化できますが、特定の引数に依存するフィーチャセットがあります。 (は完全に細かいスタイルに見なされ、標準ライブラリでさえもそうです)

関連する問題