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

标签 c++ c++11 templates visual-c++

前几天我也遇到过这个问题。

#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 再次正常工作。

Makeshift void_t 仅用于符合 C++11 的编译器。

最佳答案

MSVC 尚未发布符合 C++11 标准的编译器。

他们剩下的最大问题是在 SFINAE 上下文中使用 decltype

他们定期改进这种情况,使越来越多的 decltype 案例发挥作用,但并不可靠。

当出现问题时,它的破坏方式通常会产生误报和漏报,并且失败是非局部的,因为您之前使用 SFINAE 表达式的方式可能会改变它下次成功或失败的方式。

您根本无法在 MSVC 中安全地使用基于 decltype 的 SFINAE,除非您仔细解码您的特定版本的 MSVC 可以处理的内容,并且永远不要离开这些界限。我个人发现他们对什么有效、什么无效的描述不够清晰,让我觉得我可以可靠地使用它。

关于c++ - MSVC - 使用 void_t 进行成员检测无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40593776/

相关文章:

c++ - 在这种情况下重载 bool 运算符是否危险

c++ - std::map with key as templated structs with enum member

django 模板 - 解析字符串变量中的变量

javascript - Backbone JS 正确填充模型/集合

c++ - 如何优化 C++ 中有关 CPU 和内存的大量映射插入

c++ - 在 Qt/QML 中显示错误消息

c++ - 为什么我会收到这么多错误,为什么它告诉我窗口未定义?不会编译

c++ - 为什么隐式生成的构造函数(等)比用户定义的(普通的)构造函数更有效?

c++ - 混合 pthread.h 和 C++11 标准库线程功能是否安全?

c++ - 控制 lambda 的生命周期