如何使用三元运算符创建指向多态类的唯一指针?

Posted

技术标签:

【中文标题】如何使用三元运算符创建指向多态类的唯一指针?【英文标题】:How to make unique pointers to polymorphic classes using the ternary operator? 【发布时间】:2020-02-23 22:40:18 【问题描述】:

我正在尝试使用三元运算符设置变量。但是,编译器抱怨不兼容的类型。我确信有办法做到这一点。我已经尝试对基类进行静态转换,但我无法获得正确的语法。

#include <iostream>
#include <memory>
struct A

    virtual ~A() = default;
    virtual void test() std::cout << "A" << std::endl; 
;

struct B: public A

    void test() final std::cout << "B" << std::endl; 
;

struct C: public A

    void test() final std::cout << "C" << std::endl; 
;

int main()

    bool t = true;
    // Try to cast try a base unique class ptr. Maybe use static_cast??
    std::unique_ptr<A> aptr = t ? std::make_unique<B>(): std::make_unique<C>();
    aptr->test();

【问题讨论】:

:两侧的表达式类型必须相同或至少可以相互转换。在你的情况下,它们不是,所以你根本不能使用三元表达式。哪个 IMO 是一件好事,因为它往往会使代码更难阅读,因此也更难维护。 +1 @Someprogrammerdude 你提到可读性很有趣。我花了一个小时从这段代码中找出一个错误,因为我翻转了逻辑操作。我花了更长的时间才意识到这个问题,因为三元运算符使它更难阅读。 【参考方案1】:

三元表达式的返回值是两个表达式的共同类型(实际上std::common_type 可能使用三元运算符作为其实现的一部分:-)。

std::unique_ptr&lt;B&gt;std::unique_ptr&lt;C&gt; 是不相关的类型,

std::unique_ptr&lt;B&gt;std::unique_ptr&lt;C&gt; 都可以转换为 std::unique_ptr&lt;A&gt;,因此显式转换一个就足够了:

auto aptr = t ? std::unique_ptr<A>std::make_unique<B>()
              : std::make_unique<C>();

Demo

【讨论】:

@AProgrammer:添加了演示。是的,它可以std::unique_ptr&lt;C&gt; 可转换为std::unique_ptr&lt;A&gt; @AProgrammer 你不需要在每一边都使用相同的类型,你只需要一种类型可以转换为另一种类型,或者两种类型都可以转换为通用的原始类型。 @Jarod42,我的错。看来我再也看不懂代码了。是时候回家了。【参考方案2】:

试试这个:

std::unique_ptr<A> aptr = t ? std::unique_ptr<A>(new B()): std::unique_ptr<A>(new C());

【讨论】:

以上是关于如何使用三元运算符创建指向多态类的唯一指针?的主要内容,如果未能解决你的问题,请参考以下文章

如何从指向多态基类的指针复制/创建派生类实例?

在 C++ 三元运算符中使用字符串常量是对非左值数组的无效使用吗?

三元运算 函数

确定多态 C++ 类的大小

第二十二节,三元运算

C-switch语句, 逻辑运算符, 三元运算符, 指针与函数