ControllerSender
является базовым классом, и несколько классов будут прямыми потомками этого (только BasicSender
в этом примере) и будут созданы с помощью фабричной функции MidiControllers::AddSender
.
Указатель наэкземпляр объекта, наряду с другой информацией, хранится на карте. Последовательность построения информации на карте - сначала получить ключ (id) с AddController
и поместить нового члена на карту с значением по умолчанию Capabilities
. Затем AddOutputPtr
помещает в Capabilities
для этой клавиши shared_ptr
для устройства вывода. Наконец, AddSender
создает нового отправителя для этого ключа, полученного из ControllerSender
. Это третий шаг, который завершается неудачей.
Заводская функция выдает эту ошибку компилятора:
binary '=': не найден оператор, который принимает правый операнд типа«станд :: unique_ptr> '(или нет приемлемого преобразования) с [_Ty = BasicSender]
Ошибка:
controllers_.at(id).sender_ = std::make_unique<BasicSender>(ptr);
Если я изменю BasicSender
на базовый класс (ControllerSender
) строка компилируется без ошибок. Я думал, что это назначение должно автоматически выгружать указатель, как объяснено в Является ли unique_ptr к unique_ptr автоматическим повышением частоты? .
Как мне это исправить?
#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_;
};