2017-07-07 7 views
0

私は次のコードを持っている:intは確かであるとして、このコードでのstd :: STDを前提enable_if :: is_convertible正しくテンプレートを推測ない

#include <iostream> 
#include <type_traits> 

template <typename T, typename std::enable_if 
           <std::is_convertible<int, T>::value, T>::type> 
void func(T a) 
{ 
    std::cout << a << std::endl; 
} 

template <typename T, typename std::enable_if 
           <!std::is_convertible<int, T>::value, T>::type> 
void func(T a) 
{ 
    a.print(); 
} 

class Test 
{ 
public: 
    void print() 
    { 
     std::cout << "Test" << std::endl; 
    } 
};  

int main() 
{ 
    func(3); 
    func("Test"); 
    return 0; 
} 

を、私は(3をプリントアウトするfuncの最初の呼び出しを期待しましたintに変換可能、最初の特殊化を呼び出す必要があります)、を呼び出してTestを出力します(Test()intに変換されないため、2番目の特殊化を呼び出す必要があります)。

template <typename T, typename std::enable_if 
           <std::is_convertible<int, T>::value, T>::type* = 
            nullptr> 
void func(T a) 
{ 
    std::cout << a << std::endl; 
} 

template <typename T, typename std::enable_if 
           <!std::is_convertible<int, T>::value, T>::type* = 
            nullptr> 
void func(T a) 
{ 
    a.print(); 
} 

はその後、すべてがコンパイルした作品:(まったく同じ他のすべてを残したまま)、しかし、私が代わりにするテンプレートの機能を変更した場合

prog.cpp: In function ‘int main()’:

prog.cpp:27:8: error: no matching function for call to ‘func(int)’

prog.cpp:5:6: note: candidate: template [class T, typename std::enable_if[std::is_convertible[int, T>::value, T>::type > void func(T)

prog.cpp:5:6: note: template argument deduction/substitution failed:

prog.cpp:27:8: note: couldn't deduce template parameter ‘[anonymous>’

:しかし、私の代わりに、コンパイラのエラーを取得します私の期待通りに。この余分な構文は何ですか、なぜ私はそれを必要としますか?

+0

[std :: enable \ _ifはどのように機能するのですか?](https://stackoverflow.com/questions/25284499/how-does-stdenable-if-work) –

答えて

4
template<typename T, typename std::enable_if<std::is_convertible<int, T>::value, T>::type> 

我々はノイズを除去した場合、その2番目のパラメータとして、ここではtypenameは、ネストされたtype指定された非型パラメータを宣言している

template<typename T, typename Something<T>::type> 

になるの名前であるだろうタイプ。詳細については、hereを参照してください。

最初のケースでは、2番目のパラメータは非タイプなので、func(3)という関数呼び出しは、func<int, some_int>(3)が必要なテンプレートに適合しません。

+0

@downvoterは親切に説明して、私は興味をそそられていますあなたが質問に答えていないのは、なぜこれが下降の価値があると知覚されるのかです。 –

+0

私は質問自体に、デフォルトのパラメータ 'nullptr'を指定することで問題が解決したことに気付きました。なぜデフォルトパラメータが必要ですか? –

+1

@R_Kapp私は最初の3つの文で答えました。あなたがSFINAEに精通していないと仮定したので、以下のすべてが追加されます。 –

関連する問題