C++ std变量和转发声明

C++ std变量和转发声明,c++,c++17,variant,reference-wrapper,C++,C++17,Variant,Reference Wrapper,我的理解是,std::variant不能直接保存引用 然而,std::reference\u wrapper是一种完全限定的类型,可以放入std::vector之类的东西中,而且由于可以生成引用包装的向量,我想象可以对std::variant做同样的事情 以下代码(编辑为更简单)在gcc中生成了大量错误: #include <functional> #include <variant> class Foo; class Baz; template<typenam

我的理解是,
std::variant
不能直接保存引用

然而,
std::reference\u 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 {

};
#包括
#包括
Foo类;
Baz类;
模板结构CRef:std::reference\u包装器{
CRef(const T&x):标准::参考包装(x)
{
}
};    

模板结构包含:public std::variant这是对同一问题的一个简短复制:

int getSize(std::variant<int, char> var)
{
    return std::visit([](auto const& x){ return sizeof(x); },
        std::cref(var));
}
intgetsize(std::variant var)
{
return std::visit([](auto const&x){return sizeof(x);},
标准:cref(var));
}
问题是,您正试图将
引用\u包装传递到
std::visit
。。。但这违反了
std::visit
的要求-它需要采取实际的
std::variant
s(在最初的OP中,对象从
std::variant
中删除得更多-它是一个从
std::variant
继承的类型继承的类型的引用包装器-但是与
variant
的距离无关紧要)


你需要传递确切的变量。在我的简短示例中,这只是传递
var
而不是
std::cref(var)
。在OP中,这是将
*这个
转换为
变量常量&
,以获得正确的类型
Ts…

。在未来,我们确实关心“最小值”在这个例子中,有很多代码对演示这个问题没有帮助。这里只是注释了一些东西:(我添加了一个分号)。根据您的要求,示例已简化。您较短的复制版本发现了原件的一个问题,对此我深表歉意。即使我在访客中取消了对CRef的调用,也会出现另一个问题。虽然这确实发现了我最初发布的代码的一个问题(这是错误地围绕变量构造引用并将其传递给std visit,而不是直接传递变量),删除它仍然表明我正在做的其他事情是错误的。@markt1964这是相同的问题-您传递的是类型不是
variant
的东西。