我有一个
std::variant
,它的替代品都是指针。
class a {
public:
int* placeholder;
a(a& _copy) { /* Does a deep copy */ }
}
class b {
// For demonstrational purposes, identical to a.
}
int main() {
std::vector<std::variant<a*, b*>> instances = // initialise vector, guaranteed no nullptrs.
}
现在,例如,如果我想将第一个元素的深层副本推到后面,我不能简单地执行
instances.push_back(instances[0])
,因为这会执行 vector
的浅表副本。
当然,显而易见的解决方案是检查所有替代方案,然后
get_if
,创建一个副本,然后返回该副本。但是,我认为必须有更好的方法。类似这样的事情应该怎么做?
我也愿意接受不使用变体的解决方案。
正如评论中提到的,您可以使用
std::visit
。我强烈建议使用智能指针。
#include <variant>
#include <memory>
#include <iostream>
int main() {
// init and print x
std::variant<std::unique_ptr<int>,std::unique_ptr<std::string>> x = std::make_unique<std::string>("foo");
auto print = [](const auto& x) { std::cout << *x << "\n";};
std::visit(print,x);
// make the copy
auto deep_copy = [](const auto& x) -> std::variant<std::unique_ptr<int>,std::unique_ptr<std::string>> {
return std::make_unique<std::remove_reference_t<decltype(*x)>>(*x);
};
auto y = std::visit(deep_copy,x);
std::visit(print,y);
// check that it actually is a deep copy
auto modify = [](auto& x) { *x += 'a';};
std::visit(modify,x);
std::visit(print,x);
std::visit(print,y);
}
输出:
foo
foo
fooa
foo