MSVC - 使用 void_t 进行成员检测无法正常工作

MSVC - Member detection with void_t doesn't work properly

本文关键字:常工作 工作 检测 成员 void 使用 MSVC      更新时间:2023-10-16

我前几天遇到过这种情况。

#include <iostream>
#include <type_traits>
using namespace std;
template<typename... Ts> struct make_void { typedef void type; };
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
template <class, class = void>
struct is_func_chrend_ : std::false_type {};
template <class T>
struct is_func_chrend_<T, ::void_t<decltype(std::declval<T>().NextTile())>> : std::true_type {};
template <class = void, class = void>
struct is_addable : std::false_type {};
template <class T>
struct is_addable<T, ::void_t<decltype(std::declval<T>() + std::declval<T>())>> : std::true_type {};
int main() {
    cout << is_addable<int>::value << endl;
    return 0;
}

在MSVC中编译时显示0,在clang或gcc中编译时显示1。完全去除is_func_chrend_使is_addable重新正常工作

临时void_t仅用于c++ 11兼容的编译器

MSVC尚未发布兼容c++ 11的编译器。

他们最大的问题是decltype在SFINAE环境中使用。

他们定期改善情况,使越来越多的decltype案例工作,但它并不可靠。

当事情出错时,它被破坏的方式经常产生假阳性和假阴性,并且失败是非局部的,因为您以前使用SFINAE表达式的方式可以改变下一次成功或失败的方式。

你根本不能在MSVC中安全地使用基于decltype的SFINAE,除非你仔细解码你的MSVC特定版本可以处理的内容,并且永远不要离开这些界限。我个人觉得他们对哪些是可行的,哪些是不可行的描述不够清楚,我觉得我可以可靠地使用它。