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

时间:2016-03-23 12:16:56

标签: 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。

1 个答案:

答案 0 :(得分:3)

代码不应该编译;如果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以获得更灵活的解决过载歧义的方法。