std :: is_base_of和std :: is_convertible之间的区别

时间:2019-03-13 01:37:55

标签: c++ templates

这两个模板似乎产生相同的结果。有什么区别,什么时候应该使用?

using namespace std;

class A {

};

class B : public A {

};

class C : public A {

};

int main()
{
    cout << boolalpha << is_convertible<B, A>::value << '\n';
    cout << boolalpha << is_base_of<A, B>::value << '\n';

    cout << boolalpha << is_convertible<B, C>::value << '\n';
    cout << boolalpha << is_base_of<C, B>::value << '\n';

    return 0;
}

运行程序后,我得到了

true
true
false
false

谢谢!

1 个答案:

答案 0 :(得分:2)

看看std::is_base_ofstd::is_convertible的文档。

有一些区别:

#include <type_traits>

struct anything_can_convert_to {
    // This constructor constructs from anything
    template<class T> anything_can_convert_to(T&&) {}
};

struct can_convert_to_anything {
    // This conversion operator can convert to anything
    template<class T> operator T() { return *static_cast<T*>(nullptr); }
};

struct cant_convert_to_base;

struct base {
    base(const cant_convert_to_base&) = delete;
};

struct public_derived : base {};

struct private_derived : private base {};

struct cant_convert_to_base : base {};

int main() {
#define IS_CONVERTIBLE(FROM, TO) static_assert(std::is_convertible_v<FROM, TO>)
#define IS_NOT_CONVERTIBLE(FROM, TO) static_assert(!std::is_convertible_v<FROM, TO>)
#define IS_BASE_OF(BASE, DERIVED) static_assert(std::is_base_of_v<BASE, DERIVED>)
#define IS_NOT_BASE_OF(BASE, DERIVED) static_assert(!std::is_base_of_v<BASE, DERIVED>)

    IS_CONVERTIBLE(int, long);
    IS_CONVERTIBLE(int, anything_can_convert_to);
    IS_CONVERTIBLE(can_convert_to_anything, int);
    IS_NOT_CONVERTIBLE(anything_can_convert_to, int);

    IS_CONVERTIBLE(public_derived, base);
    IS_NOT_CONVERTIBLE(private_derived, base);
    IS_NOT_CONVERTIBLE(cant_convert_to_base, base);


    IS_NOT_BASE_OF(int, long);
    IS_NOT_BASE_OF(int, anything_can_convert_to);

    IS_BASE_OF(base, public_derived);
    IS_BASE_OF(base, private_derived);
    IS_BASE_OF(base, cant_convert_to_base);
}

您将意识到它们是针对两种不同的事物的。 std::is_base_of<Base, Derived>确实听起来像:在继承方面,Base是否是Derived的基类。 std::is_convertible<From, To>主要检查是否:

To test = (expression of type From);

格式正确。对于继承,大多数情况是FromTo的基类,但是在很多其他情况下都是这种情况(例如,对于私有继承,您不能转换为基础,但std::is_base_of仍然有效。)