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
или что угодно