2

以下代碼大部分摘自Piotr Skotnicki的answer。我用它進行試驗,發現了我認爲是MSVC 14.0更新錯誤3.當我更改類型參數名稱時,模板替換失敗 - 編譯器錯誤?

考慮下面的代碼:

#include <iostream> 

template <typename T> 
struct identity { using type = T; }; 

template <typename...> 
using void_t = void; 

template <typename F> 
struct call_operator; 

template <typename C, typename R, typename... A> 
struct call_operator<R(C::*)(A...)> : identity<R(A...)> {}; 

template <typename C, typename R, typename... A> 
struct call_operator<R(C::*)(A...) const> : identity<R(A...)> {}; 

template <typename F> 
using call_operator_t = typename call_operator<F>::type; 

template <typename, typename = void_t<>> 
struct is_convertible_to_function 
    : std::false_type {}; 

template <typename L> 
struct is_convertible_to_function<L, void_t<decltype(&L::operator())>> 
    : std::is_assignable<call_operator_t<decltype(&L::operator())>*&, L> {}; 

template <typename, typename = void_t<>> 
struct is_callable_object 
    : std::false_type {}; 

template <typename L> 
struct is_callable_object<L, void_t<decltype(&L::operator())>> 
    : std::true_type {}; 


int main() 
{ 
    auto x = []() {}; 
    std::cout << std::boolalpha << is_callable_object<decltype(x)>::value; 
    std::getchar(); 
} 

這將打印true,符合市場預期,因爲所產生的拉姆達對象編譯器確實實現了operator()

現在讓我們在is_callable_objectL改變類型參數名稱T(任何從is_convertible_to_function導致此問題所使用的類型名稱不同,從我所看到的)。

template <typename, typename = void_t<>> 
struct is_callable_object 
    : std::false_type {}; 

template <typename T> 
struct is_callable_object<T, void_t<decltype(&T::operator())>> 
    : std::true_type {}; 

突然,這種打印falseis_convertible_to_funtion應該無關緊要,因爲is_callable_object不以任何方式依賴它;的確,如果我刪除is_convertible_to_function,這個問題就會消失 - 我可以使用任何我想要的類型名稱。正如我所說,我懷疑這是一個錯誤,所以我問這個問題,以確保這不是在C++標準中的一些奇怪的行爲;解決這個問題的辦法很簡單。

回答

2

表達式sfinae在msvc 2015中不起作用。任何運行的情況都是偶然的,不要相信它。 decltype不能用於在msvc 2015中可靠地導致sfinae

停下來,走開,找到另一個解決方案。也許嘗試編譯器內在函數。

當參數名稱匹配意味着其他任何東西都可以工作時,不要假定偶然的工作方式,否則它將工作在稍微不同的程序中。

您的解決方法是不可信的。

+0

我想知道您的聲明是不是太過分極端,但即使是微軟自己也承認:https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-表達-SFINAE-在-VS-2015-更新-1 /。哦,我會繼續試驗,謝謝。 – szczurcio

相關問題