2017-09-30 3 views
0

を生成し、私は2つのテストクラスを作ってきました。 Tがデフォルトで構成可能でない場合、2番目のものは "失敗"します。タイプSFINAEはコンパイルが、エラー

template<typename T> 
T* CreateInstanceTest(char*[!std::is_default_constructible<T>::value] = 0) { return nullptr; } 

template<typename T> 
T* CreateInstanceTest(char*[std::is_default_constructible<T>::value] = 0) { return new T(); } 

それから私はこれを行う:

「オーバーロードされた関数の複数のインスタンスが 『CreateInstanceTestは、』引数リストと一致した」エラーが発生し
Class1* obj1 = CreateInstanceTest<Class1>(); 
Class2* obj2 = CreateInstanceTest<Class2>(); 

ただし、正常にコンパイルされ、期待どおりに動作します。 obj1がnullになり、obj2が適切に作成されます。

どうしてですか?それを回避する方法はありますか?

+0

エラーは発生しますが、コンパイルは問題ありませんか? – Zereges

+0

はい。テキストが赤くなり、「エラーリスト」にエラーが表示されますが、正常に構築され、プログラムを実行できます。期待どおりに動作します。 – MyNiceDisplayName

+0

は 'std :: enable_if_t'を使います。 – Jarod42

答えて

3

ビルドエラーではなく、Intellisenseエラーです。インテリセンスは完璧ではありませんが、回避策として控除コードを改善することができます:

template<typename T> typename ::std::enable_if_t 
< 
    !::std::is_default_constructible<T>::value 
, T * 
> 
CreateInstanceTest(void) { return nullptr; } 

template<typename T> typename ::std::enable_if_t 
< 
    ::std::is_default_constructible<T>::value 
, T * 
> 
CreateInstanceTest(void) { return new T(); } 
+0

ありがとう実際にはエラーは発生しません。 それはまた、私が望むことをやるためのより良い方法のように見えます。 – MyNiceDisplayName

+0

'std'の代わりに' :: std'を使う理由はありますか?誰かが 'std'を自分の識別子として使っているとは思わない。 – Zereges

+0

@Zereges実際には時々起こります。例えば、人々は何かを 'std'名前空間に持っていきますが、スコープを使いこなし、ルートの代わりにネストした' std'名前空間を生成します。常に安全な側にいるほうが良いし、先頭の '::'を使うと落とし穴がないので、いつも使っている傾向があります。 – VTT

関連する問題