【问题标题】:How to make class A convertible to class B如何将A级转换为B级
【发布时间】:2021-09-17 18:38:54
【问题描述】:

这里有两个基本不相关的类:

class A {};

class B {};

以及检查这两个AB 类的可转换性的概念:

template<typename FROM, typename TO>
concept SafelyConvertible = 
    is_convertible<typename FROM::pointer, typename TO::pointer>::value &&
    !is_array<typename TO::element_type>::value
;

上述 SafelyConvertible 概念中的 FROM 和 TO 预计是自定义智能指针实现,提供指针 typedef:

template<typename T>
class smart_ptr {
    using pointer = T*;
...
};

目标只是使A 可转换为B,以便将概念SafelyConvertible 评估为true

我尝试在 B 中实现转换构造函数:

class B {
    B( const A & other ) { ... }

    B( A && other ) { ... }
};

但不知何故,它并没有使 A 转换为 B...提前感谢任何愿意提供帮助的人

【问题讨论】:

  • 您正在尝试检查A*是否可以转换为B*,而不是A是否可以转换为B,因此复制构造函数在这里实际上是无用的。 C++ 并没有隐式地允许不同类型的指针相互转换。
  • @Ruks - 好的,那么如何使指针显式可转换?有什么提示吗?
  • 要使指针可转换,您需要在AB 之间建立某种继承关系。

标签: c++ constructor type-conversion c++20


【解决方案1】:

您正在尝试检查A* 是否可以转换为B*,而不是A 是否可以转换为B,因此在这种情况下,复制构造函数和移动构造函数实际上是无用的。 C++ 并没有隐式地允许不同类型的指针相互转换。

两个类的指针只有在其中一个类派生自另一个类时才能隐式转换,即:

#include <type_traits>

class A {};
class B : public A {};

int main()
{
    static_assert(std::is_convertible_v<B*, A*>, "ERROR"); // OK
    static_assert(std::is_convertible_v<A*, B*>, "ERROR"); // ERROR
}

或者:

#include <type_traits>

class B {};
class A : public B {};

int main()
{
    static_assert(std::is_convertible_v<B*, A*>, "ERROR"); // ERROR
    static_assert(std::is_convertible_v<A*, B*>, "ERROR"); // OK
}

或者,您可以使用 std::remove_pointer 从对应的指针中获取类型:

#include <type_traits>

// ...

template<typename FROM, typename TO>
concept SafelyConvertible = 
    is_convertible_v<std::remove_pointer_t<typename FROM::pointer>, std::remove_pointer_t<typename TO::pointer>> &&
    !is_array_v<typename TO::element_type>;

// ...

【讨论】:

  • 或者直接使用类型而不分别从 FROM 和 TO 中提取它们?
  • @MartinKopecký 你为什么要谈论指针?如果AB 是不相关的类型,则不能将指向其中一个的智能指针存储在指向另一个的智能指针中。
  • C++ 确实允许不同类型的指针相互转换,而不是两个不相关的类的指针
【解决方案2】:

is_convertible 如果 FROM 可以隐式转换为 TO,则返回 true。当且仅当 TO 可以从 FROM 复制初始化时,这种转换是可能的,换句话说,如果

    TO to = from;// (type FROM)

此语句已成功编译,因此这些对象是可转换的。否则这种转换是不可能的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    相关资源
    最近更新 更多