微軟編譯器(Visual Studio中2017 15.2)拒絕以下代碼:重載分辨率
#include <type_traits>
struct B
{
template<int n, std::enable_if_t<n == 0, int> = 0>
void f() { }
};
struct D : B
{
using B::f;
template<int n, std::enable_if_t<n == 1, int> = 0>
void f() { }
};
int main()
{
D d;
d.f<0>();
d.f<1>();
}
錯誤是:
error C2672: 'D::f': no matching overloaded function found
error C2783: 'void D::f(void)': could not deduce template argument for '__formal'
note: see declaration of 'D::f'
鏘也拒絕它:
error: no matching member function for call to 'f'
d.f<0>();
~~^~~~
note: candidate template ignored: disabled by 'enable_if' [with n = 0]
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
GCC完全接受它。哪個編譯器是正確的?
增加:
隨着SFINAE在
template<int n, typename = std::enable_if_t<n == 0>>
...
template<int n, typename = std::enable_if_t<n == 1>>
GCC還產生一個錯誤的形式:
error: no matching function for call to ‘D::f<0>()’
d.f<0>();
^
note: candidate: template<int n, class> void D::f()
void f()
^
note: template argument deduction/substitution failed:
無關:您可能需要使用一個虛函數SFINAE基類和派生方法來區分,而不是。 –
@HenriMenke我不知道原始用例是什麼,你也不知道,但是虛函數實現了與這裏顯示的完全不同的東西。這是利用實現繼承,而不是多態,並且它使得這兩個函數對於D的用戶可用。虛擬是關於多態的,並且它只有一個可用於D的用戶的功能。 –
@ Jarod42固定標籤,謝謝。 – Evgeny