C++使用SFINAE检测任何构造函数

标签 c++ templates sfinae

我尝试创建一个模板类,它应该使用 SFINAE 和可变参数模板检测任何构造函数。这是模板的代码:

template <typename Type, typename ... Arguments>
struct IsConstructible
    {

        template <typename U, decltype(U(Arguments...))* = nullptr>
        static char test();
        template <typename U>
        static long test(...);

        static constexpr bool value = sizeof(test<Type>()) == sizeof(char);

    };

但是,当我使用以下类型对此进行测试时:

struct MyBadType {

    MyBadType(int x) { }

};

结果:

IsConstructible<MyBadType, int>::value;

是 0。我的模板检查器有什么问题吗?我正在使用 MSVS 2015 Express。

最佳答案

代码不应该编译;如果 MSVC 这样做,那么它正在使用扩展。

template <typename U, decltype(U(Arguments...))* = nullptr>

那个decltype表达没有意义。 U(Arguments...)是一个函数类型,但是你想获取构造一个U的类型来自 Arguments... .你可以使用 std::declval为此:

template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr>

还有第二个问题:

    template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr>
    static char test();
    template <typename U>
    static long test(...);

电话test<type>()会模棱两可。解决歧义的“经典”方法是为首选版本提供一个虚拟参数:

    template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr>
    static char test(int);
    //          here ^^^
    template <typename U>
    static long test(...);

然后你调用像test<type>(0)这样的函数.

Live Demo


参见 this blog post以更灵活的方式解决重载歧义。

关于C++使用SFINAE检测任何构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36177951/

相关文章:

c++ - vector 上的for循环,总是返回一个索引

c++ - 如何将编译时字符串 (BOOST_METAPARSE_STRING) 转换为运行时字符串?

c++ - 检查类是否在继承层次结构中明确定义成员类型

c++ - Linux C++ 编译错误

c++ - 根据调用的构造函数更改成员数

c++ - SFINAE 的模板特化

c++ - 这是使用docker开发多层C/C++应用程序的好方法吗?

C++机票费用计算项目

c++ - 广泛使用OpenGL绘制世界地图[WGS84]

c++ - 使用 int 作为直到运行时才知道的模板参数