2017-08-15 2 views
6

のコンパイルに失敗++:今メイクCは私がようにテンプレート機能を持つプロジェクトに取り組んでいるテンプレート関数の特定のインスタンス化

template <class T> 
T foo<T>(T val) { return someFunc(val); } 

template <> 
bool foo<bool>(bool val) { return otherFunc(val); }; 

、私はしたくないクラスBarを、持っています入力として受け入れる。実際、コンパイルエラーを見つけるのは簡単です。問題は私がこれを行う場合です:

template <> 
Bar foo<Bar>(Bar val) { static_assert(false,"uh oh..."); } 

すべてのコンパイルで失敗します。私はhttps://stackoverflow.com/a/3926854/7673414を見つけました。テンプレートタイプを参照する必要があると言われています。それ以外の場合は、常に静的なアサートが行われます。問題は、ここにテンプレートタイプがないことです。私がそうするなら:

template< typename T > 
struct always_false { 
    enum { value = false }; 
}; 

template <> 
Bar foo<Bar>(Bar val) { static_assert(always_false<Bar>::value,"uh oh..."); } 

それはまた、常にコンパイルに失敗します。タイプBarのテンプレートのインスタンス化で、常にコンパイルエラーが発生することを確実にする方法はありますか?

答えて

18

fooが完了専門なので、それは常にコンパイルされます、そして静的アサートは常に呼び出されます。

しかし、easier wayがあります:

template <> 
Bar foo<Bar>(Bar val) = delete; 

これは、この特定のバージョンが削除され、呼び出すことはできませんと言うだろう。

+0

それはいいですが、私は様々なc - torsをすべて削除する代わりに、d - torを削除したいと思います。 –

+1

@ YehezkelB。これはクラステンプレートではなく、関数テンプレートです。コンストラクタやデストラクタだけでなく、関数テンプレートの特殊化を削除できます。 –

2

std::is_sameを使用して、要件を満たすことができます。

template <class T> 
T foo<T>(T val) 
{ 
    // Make sure T is not Bar 
    static_assert(std::is_same<T, Bar>::value == false, "uh oh..."); 
    return someFunc(val); 
} 
+1

で利用可能ですか! –

+0

@FengWang、done。それを指摘してくれてありがとう。 –

3

もう一つの方法は、あなたがC++ 14を使用することができた場合はタイプがBar

template <class T> 
typename std::enable_if< ! std::is_same<T, Bar>::value, T>::type foo<T>(T val) 
{ return someFunc(val); } 

と異なっている場合にのみ、テンプレート(ない特殊なバージョン)を有効にし、std::enable_if_t

template <class T> 
std::enable_if_t< ! std::is_same<T, Bar>::value, T> foo<T>(T val) 
{ return someFunc(val); } 
を使用して簡素化することができますされていますあなたがC++ 17を使用している場合は
1

、あなたはconstexpr ifと一緒にすべてを置くことができます。

template< typename T > 
auto foo(T val) 
{ 
    static_assert(!std::is_same_v<T,Bar>); 

    if constexpr(std::is_same_v<T,bool>) 
    { 
     return other_func(val); 
    } 
    else 
    { 
     return some_func(val); 
    } 

} 

その後、最初の行でstatic_assertを実行すると、テンプレート固有のインスタンス化のコンパイルに失敗することなく苦労することはありません。

ライブの例では、あなたが不足している `)` `のためstatic_assert`を追加してくださいだろうhttps://wandbox.org/permlink/PpR6G0gcvMRoxhhZ

関連する問題