c++ - 为什么在此示例中从 unique_ptr<derived> 自动向上转换到 unique_ptr<base> 失败?

标签 c++ c++11 unique-ptr upcasting

ControllerSender 是基类,几个类将是它的直接子类(本例中只有 BasicSender)并通过工厂函数 MidiControllers 实例化::添加发件人

指向实例化对象的指针以及其他信息存储在映射中。在 map 中构建信息的顺序是首先使用AddController 获取键(id),并在 map 中放置一个新成员,默认为Capabilities。然后 AddOutputPtrCapabilities 中为该键放置一个 shared_ptr 到输出设备。最后,AddSender 为从 ControllerSender 派生的 key 创建一个新的发件人。这是失败的第三步。

工厂函数抛出这个编译器错误:

binary '=': no operator found which takes a right-hand operand of type 'std::unique_ptr<BasicSender,std::default_delete<_Ty>>' (or there is no acceptable conversion) with [_Ty=BasicSender]

失败的行是

controllers_.at(id).sender_ = std::make_unique<BasicSender>(ptr);

如果我将 BasicSender 更改为基类 (ControllerSender),则该行编译没有错误。我认为这个赋值应该自动向上转换指针,如 Is unique_ptr<Derived> to unique_ptr<Base> up-casting automatic? 中所述。 .

我该如何解决这个问题?

#include <map>
#include <vector>
#include <JuceLibraryCode/JuceHeader.h>

class ControllerSender {
 public:
   ControllerSender(std::shared_ptr<juce::MidiOutput>& device) : device_(device) {}

 private:
   std::shared_ptr<juce::MidiOutput> device_{};
};

class BasicSender : ControllerSender {
 public:
   using ControllerSender::ControllerSender;
};

class MidiControllers {
 public:
   void AddController(const juce::MidiDeviceInfo& id)
   {
      controllers_.insert({id, Capabilities{}});
   }
   void AddOutputPtr(const juce::MidiDeviceInfo& id, std::shared_ptr<juce::MidiOutput>& device)
   {
      controllers_.at(id).device_ = device;
   }
   void AddSender(const juce::MidiDeviceInfo& id, std::string sender_name)
   {
      auto& ptr = controllers_.at(id).device_;
      if (ptr) {
         if (sender_name == "BasicSender") {
            controllers_.at(id).sender_ = std::make_unique<BasicSender>(ptr);
         }
      }
   }

 private:
   struct Capabilities {
      std::shared_ptr<juce::MidiOutput> device_{nullptr};
      std::unique_ptr<ControllerSender> sender_{nullptr};
   };

   struct IdentifierComp {
      bool operator()(const juce::MidiDeviceInfo& lhs, const juce::MidiDeviceInfo& rhs) const
          noexcept
      {
         return lhs.name < rhs.name || lhs.identifier < rhs.identifier;
      }
   };
   std::map<juce::MidiDeviceInfo, Capabilities, IdentifierComp> controllers_;
};

最佳答案

问题是你使用了私有(private)继承:

class BasicSender : ControllerSender

这意味着没有从BasicSender *ControllerSender *的隐式转换,因此相应的智能指针没有隐式转换。

要修复,请使用 public:

class BasicSender : public ControllerSender

(或使用 struct 关键字而不是 class,这意味着默认访问是公开的)。

关于c++ - 为什么在此示例中从 unique_ptr<derived> 自动向上转换到 unique_ptr<base> 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58793718/

相关文章:

c++ - 如何使用 boost::crc?

c++ - 从 MFC 表单应用程序调用 Web 服务器

c++ - 如何根据其数量(或编译时已知的其他信息)以不同方式调用函数对象?

c++ - QTreeWidgetItem 的拖放不能正常工作

c++ - 您在哪里跟踪新的 c++ 标准的发展?

c++ - iterator_traits<InIter>::value_type 的创建是否会在传递时触发遵从? (异常测试)

c++ - 由已移动的唯一指针管理的对象的引用会发生什么情况?

c++ - 如何在 C++11 中编写此 C++17 静态 constexpr 方法?

c++ - uniq_ptr 直接赋值

c++ - 使用 std::make_unique 自定义初始化数组