【发布时间】:2021-12-28 20:32:17
【问题描述】:
假设我有下一个代码,用于简单地存储类型为A、B 或C 的对象的引用/指针。我实际上不需要完整的类型。
现在我有以下解决方案,我需要很多 #include 膨胀。
标题:
using MyVariant = std::variant<class A, class B, class C, ...>;
class Holder {
public:
Holder(MyVariant &&TheValue);
const MyVariant &GetValue();
private:
std::unique_ptr<MyVariant> Value;
};
源文件:
#include "A.hpp"
#include "B.hpp"
#include "C.hpp"
Holder::Holder(MyVariant &&TheValue)
: Value(std::make_unique<MyVariant>(std::move(TheValue)) {}
const MyVariant &Holder::GetValue { return Value; }
如何在没有所有实例化类型的情况下实现与 std::variant 模板参数/动态内存分配/动态多态性相同的语义?
【问题讨论】:
-
如果你只是想持有指针,那为什么不
std::variant<A*, B*, C*>呢? (或std::unique_ptr等效项)。 -
我想避免很多
new调用,所以我不能在堆栈上分配对象并将指针传递给它。而不是这个,我通常希望自己持有一个值。 -
在您当前的解决方案中,为什么使用
std::unique_ptr<MyVariant> Value;而不是MyVariant Value;?即使对于自动Holder实例,这也会将变体放入堆栈中。 -
@385i 如果您希望
std::variant实际保存没有间接的类型,那么它们在逻辑上必须是完整的,因为std::variant需要知道为它们保留多少内存。 -
@385i
variant不能用于不完整的类型,原因相同,没有任何解决方法可以满足您的所有要求。您希望对象就地存储值(没有外部存储器)。为此,对象必须至少与它可以容纳的最大类型一样大。为此,它必须知道它可以容纳的每种类型的大小。为此,每种类型都必须是完整的(您无法获得不完整类型的大小),这与您对类型不完整的要求相矛盾。
标签: c++ polymorphism variant