c++ - C++ 检测惯用法在 Visual Studio 2015 Update 2 CTP 中未按预期工作

标签 c++ templates c++14 c++17

我正在玩 proposal of standard library support for the C++ detection idiom并使用 Microsoft C/C++ 优化编译器版本 19.00.23725 for x64 编译了以下代码:

#include <iostream>


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

template<class, template<class> class, class = void_t<>>
struct detect : std::false_type { };

template<class T, template<class> class Operation>
struct detect<T, Operation, void_t<Operation<T>>> : std::true_type { };


template<class T>
using bar_t = decltype(std::declval<T>().bar());

template<class T>
using bar_int_t = decltype(std::declval<T>().bar(0));

template<class T>
using bar_string_t = decltype(std::declval<T>().bar(""));


struct foo
{
    int bar() { return 0; }
    int bar(int) { return 0; }
};


int main()
{
    std::cout << detect<foo, bar_t>{} << std::endl;
    std::cout << detect<foo, bar_int_t>{} << std::endl;
    std::cout << detect<foo, bar_string_t>{} << std::endl;

    return 0;
}

预期输出为

1
1
0

但确实如此

1
1
1

出了什么问题?我做了一个live demo (使用完全相同的代码)输出符合预期。

最佳答案

Visual C++ 对表达式 SFINAE 的支持有限,但是,我认为它应该与函数返回类型一起使用。因此,您可以尝试以下实现:

#include <type_traits>

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

template <typename, template <typename> class>
auto detect_impl(char) -> std::false_type;

template <typename T, template <typename> class Operation>
auto detect_impl(int) -> decltype(void_t<Operation<T>>(), std::true_type{});

template <typename T, template <typename> class Operation>
using detect = decltype(detect_impl<T, Operation>(0));

(在 http://webcompiler.cloudapp.net/ 上测试)

关于c++ - C++ 检测惯用法在 Visual Studio 2015 Update 2 CTP 中未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35669239/

相关文章:

c++ - 检测类中使用 CRTP 的成员函数

c++ - 设计题: Holding class metadata for dynamic lookup

c++ - SDL - 获取原生屏幕分辨率

c++ - C++ 元编程中的模板柯里化(Currying)

c++ - 范围末尾的左值可以被视为右值吗?

c++ - std::less<void> 和指针类型

c++ - 在 visual studio 中运行的主要方法不正确

c++ - Qt 对象管理与 Qt 插件

javascript - 在 ng-repeat 循环期间或循环后更改属性?

c++ - 类型检查模板参数导致的编译器错误