繁体   English   中英

enable_if SFINAE的问题

[英]Problems with enable_if SFINAE

在我写的一个程序中,我遇到了一些莫名其妙的SFINAE问题,所以我把它归结为一个独立的示例程序:

#include <type_traits>

struct Base { };

struct Derived : public Base { };

template<typename T>
struct From { };

template<typename T>
struct To {
    template<typename U>
    To(const From<U>& other) {
        static_assert(std::is_convertible<U*, T*>::value, "error");
    }
};

int main() {
    From<Derived> a;

    To<Base> b = a;
}

该程序编译时没有错误或警告。 但是,这个:

#include <type_traits>

struct Base { };

struct Derived : public Base { };

template<typename T>
struct From { };

template<typename T>
struct To {
    template<typename U>
    To(const From<typename std::enable_if<true, U>::type>& other) {
    // this       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        static_assert(std::is_convertible<U*, T*>::value, "error");
    }
};

int main() {
    From<Derived> a;

    To<Base> b = a;
}

给出以下错误:

test.cpp:在函数int main()

test.cpp:22:18:错误:从From<Base>转换为非标量类型To<Derived> request

这是因为我认为替换失败了,并且没有看到构造函数。

我在SFINAE上做错了,还是编译错误? 我在Windows上使用rubenvb的GCC 4.7.1(如果它有所不同, std=c++11 )。

我使用默认模板参数,这样可以推导出参数:

#include <type_traits>

struct Base { };

struct Derived : public Base { };

template<typename T>
struct From { };

template<typename T>
struct To {
    template<typename U, class = typename std::enable_if<true, U>::type>
    To(const From<U>& other) {
    // this       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        static_assert(std::is_convertible<U*, T*>::value, "error");
    }
};

int main() {
    From<Base> a;

    To<Derived> b = a;
}

请注意,这会导致static_assert失败,因为您std::is_convertible使用std::is_convertible 它应该是:

static_assert(std::is_convertible<T*, U*>::value, "error");

在您的示例中,无法推导出模板类型U 在我的代码中,可以推导出它,因为它被用作构造函数中other参数的模板参数。 在您的代码中,编译器会看到std::enable_if<true, U>::type ,并且无法推断出该U类型。 enable_if的结果用作From的模板参数的事实根本没有帮助,因为U需要在此之前推断出来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM