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

相关问题