gpt4 book ai didi

c++ - 标准变体和前向声明

转载 作者:行者123 更新时间:2023-11-30 04:42:46 31 4
gpt4 key购买 nike

据我了解,std::variant 不能直接保存引用。

但是,std::reference_wrapper 是一种完全限定的类型,可以放入 std::vector 之类的东西中,并且由于可以制作引用包装器的 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,在这种情况下,是唯一的端点类,尽管在实践中会有更多,并且它们没有公共(public)基类,这就是为什么我需要一个变体,而不能简单地使用一个基类类和使用虚函数。

编译器生成的错误在这里可见:https://godbolt.org/z/lcbPjB

所以,我想我可能正在做一些不允许的事情。

我的问题是,有没有办法做我正在尝试的事情?如果我的意图不清楚,我提前道歉。如果在理解我要实现的目标时遇到问题,可以留下一些专门确定我需要提供哪些额外信息的反馈,我将努力遵守。

请记住,在实际用例中,端点类要复杂得多,并且除了 getSize() 之外还会有更多函数,但我希望一旦我有了适用于这个简单案例的东西,我应该能够正确概括和实现其他功能。

最佳答案

这是对同一问题的更简短的再现:

int getSize(std::variant<int, char> var)
{
return std::visit([](auto const& x){ return sizeof(x); },
std::cref(var));
}

问题是,您正试图传递 reference_wrapperstd::visit ...但这违反了 std::visit 的要求- 它需要实际std::variant s(在原始 OP 中,该对象甚至从 std::variant 中删除 - 它是一个类型的引用包装器,该类型继承自 std::variant 的类型 - 但与 variant 的距离无关紧要) .

您需要传入确切的变体。在我的简短示例中,这只是传递 var而不是 std::cref(var) .在 OP 中,这是类型转换 *this下降到 variant<Ts...> const&对于正确的类型 Ts...

关于c++ - 标准变体和前向声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58602222/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com