std::any для объектов, которые не могут быть созданы с помощью копирования

У меня есть объект, который содержит unique_ptr и, как таковой, не может быть скопирован без создания глубокой копии (что мне не нужно).

Я бы хотел, чтобы std:: any содержал этот объект, но единственная найденная мною альтернатива - сделать так, чтобы std:: any содержал указатель, который добавляет бесполезную косвенность, или чтобы у моего объекта был уникальный ptr. Надеемся, что приведенный ниже код проиллюстрирует мою точку зрения:

//Compiled with clang++ -std=c++2a; clang version 5.0.0
#include <iostream>
#include <any>
#include <memory>

struct A {
        std::unique_ptr<int> m = std::make_unique<int>(11);
        A(A&& a): m(std::move(a.m)) {}
        A() {}
};

struct B {
        std::shared_ptr<int> m = std::make_shared<int>(11);
};


template<class T>
void use_any_ptr() {
        std::any a{new T{}};
        std::cout << *(std::any_cast<T*>(a)->m) << std::endl;
}

template<class T>
void use_any() {
        std::any a{T{}};
        std::cout << *(std::any_cast<T>(a).m) << std::endl;
}


int main() {
        use_any_ptr<A>(); // Workaround using a pointer
        use_any<B>(); // Workaround using shared pointer
        use_any<A>(); // Breaks because A has no cc no matching constructor for initialization of 'std::any'
}

Насколько я понимаю, для создания std:: any требуется копирование объекта, однако я не уверен, почему этот объект нельзя просто переместить.

Есть ли способ обойти это? То есть, кроме использования shared_ptr, что означает, что я в основном выражаю "неправильную вещь" ради создания объекта any или передачи указателя std:: any (что является ненужным уровнем косвенности, поскольку std:: любой, как я могу судить, содержит пустой указатель на тип с существованием.

Есть ли другая реализация, которая могла бы использовать ctr перемещения при создании вместо ctr копии?

Или я глупый и не понимаю "настоящую" проблему здесь?

1 ответ

Или я глупый и не понимаю "настоящую" проблему здесь?

Проблема проста здесь: std::any имеет конструктор копирования и поэтому требует, чтобы содержащийся в нем объект был копируемым.

Вы можете обойти это путем определения пользовательского объекта, который содержит указатель, который можно копировать и который реализует правильную логику для него (какими бы ни были надлежащие средства в вашем случае, я не вижу, как вы могли бы скопировать std::any и, таким образом, объект, содержащийся там, который владеет std::unique_ptr, но, может быть, вы можете сойти с рук как-то в вашем случае).

В противном случае переосмыслите свой дизайн и попытайтесь избавиться от необходимости std::any, На самом деле он не имеет большого применения, и, вероятно, вы можете получить то же самое с небольшим количеством шаблонов или std::variant или что угодно

Другие вопросы по тегам