【问题标题】:MSVC - Member detection with void_t doesn't work properlyMSVC - 使用 void_t 进行成员检测无法正常工作
【发布时间】:2016-11-14 16:46:29
【问题描述】:

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

#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 的编译器。

【问题讨论】:

  • 没有调查你的代码,但是VS没有完全实现表达式SFINAE
  • 您可能需要绝对最新的 MSVC 才能正常工作。我得到一个带有 VS2015 SP3 的1
  • @BoPersson 我在 VS2015 和 VS 15 上都得到 0,据我所知,两者都已完全更新。

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多