我的理解是std::variant
不能直接保存引用。
但是,std::reference_wrapper
是一种完全限定的类型,可以放入诸如 之类的东西std::vector
中,并且由于可以制作引用包装器的向量,我想人们可以对std::variant
.
以下(编辑得更简洁)代码在 gcc 中生成了大量错误:
#include <functional>
#include <variant>
class Foo;
class Baz;
template<typename T> struct CRef : std::reference_wrapper<const T> {
CRef(const T &x) : std::reference_wrapper<const T>(x)
{
}
};
template<typename... Args> struct Contains : public std::variant<CRef<Args>... > {
};
struct Foo : public Contains<Baz> {
int getSize() const;
};
struct getSizeVisitor {
template<typename T> int operator()(CRef<T> x) const
{
return sizeof(T);
}
};
inline int Foo::getSize() const
{
return std::visit(getSizeVisitor(), (*this));
}
struct Baz : public Foo {
};
CRef
模板只是 std::reference_wrapper 到 const 引用的方便包装器,模板的Contains
存在是为了帮助类了解基类在某些时候可能引用的所有端点子类。在上述情况下,我只是想要一个getSize()
方法,它将返回变量中包含的实际类型的大小。 Baz
,在这种情况下,是唯一的端点类,尽管实际上会有更多,并且它们没有公共基类,这就是为什么我需要一个变体,并且不能简单地使用基类并使用虚函数。
编译器生成的错误在这里可见:https ://godbolt.org/z/lcbPjB
所以,我想我可能正在做一些不允许的事情。
我的问题是,有没有办法做我正在尝试的事情?如果我的意图不清楚,我会提前道歉。如果在理解我要达到的目标时遇到问题,可以留下一些反馈,具体确定我需要提供哪些额外信息,我将努力遵守。
请记住,在实际用例中,端点类要复杂得多,并且除了 getSize() 之外还会有更多的函数,但我希望一旦我有一些适用于这个简单案例的东西,我应该能够概括和正确实现其他功能。