将由 boost::variant 聚合的类型的对象传递给接受该 boost::variant 的函数

Posted

技术标签:

【中文标题】将由 boost::variant 聚合的类型的对象传递给接受该 boost::variant 的函数【英文标题】:Pass an object of a type aggregated by a boost::variant to a function that accepts that boost::variant 【发布时间】:2011-02-23 13:10:43 【问题描述】:

假设我有:

class TypeA  ;
class TypeB  ;
typedef boost::variant<TypeA, TypeB> Type;

    没关系:

    void foo(Type t)  ;
    
    int main()
        TypeA a;
        foo(a);
    
    

    这不会编译:

    void foo(Type &t)  ;
    
    int main()
        TypeA a;
        foo(a);
    
    

    出现错误:

    “Type&”类型的引用初始化无效 “TypeA”类型的表达式

    这也不编译:

    void foo(Type *t)  ;
    
    int main()
        TypeA a;
        foo(&a);
    
    

    出现错误:

    无法将参数“1”的“TypeA*”转换为“Type*”到“void” foo(类型*)'

有没有办法通过引用(如案例 2)或指针(如案例3)?

非常感谢!

【问题讨论】:

【参考方案1】:

1 中真正发生的事情:

TypeA a;
Type __temporary__(a);
foo(__temporary__);

2 或 3 中不可能发生的事情:

TypeA a;
Type* __temporary__(&a);
  // this fails because there is no inheritance relationship
foo(__temporary__);

您有两种解决方案(对于非模板 foo):

转换为Type,然后获取指向此的指针/引用 创建一个boost::variant&lt;TypeA*,TypeB*&gt; 以进行隐式转换

第三种解决方案是更改 foo 本身,并使其成为模板。这取决于你想做什么。

【讨论】:

谢谢!但是__temporary__ 是什么意思?如果您的意思是编译器临时对象,那么它不会仅通过调用例如创建。 “富(类型A());” ?在您的第一个解决方案中,从 TypeA 到 Type 的转换是否需要副本,例如。如“TypeA a; Type t=a; foo(&t);” ?很好的第二个解决方案,我会考虑的!至于模板,我怎么能适应没有公共基类的不相关的TypeA和TypeB? @Francesco:编译器将a 复制到Type(变体)类型的临时对象中,然后使用此临时对象执行对foo 的调用。 // 模板适用于不相关的类型,只要两者都存在所需的方法。【参考方案2】:

聚合意味着boost::variant 包含TypeATypeB。它没有。它包含TypeATypeB。它更像是一个联合而不是一个结构。

您可以按值传递TypeA,因为存在从TypeAType 的隐式转换。

没有从TypeA&amp;Type&amp;(或TypeA*Type*)的隐式转换,也不应该存在。想想如果对 TypeA 对象的引用被传递到 foo() 并且 foo() 决定用 TypeB 值替换它会发生什么。

不知道foo()TypeA/TypeB 是什么,我不能给你更具体的建议,但也许你可以使用函数模板。即

template <typename T>
void foo(T& t) 

或重载函数:

void foo(TypeA& t) 
void foo(TypeB& t) 

【讨论】:

谢谢!重载函数可能是一个解决方案。至于模板,我怎么能适应没有公共基类的不相关的TypeA和TypeB? 模板不关心实际的参数类型。唯一重要的是,您对类型参数化对象执行的任何操作都对实际类型的对象有效。如果两种类型的代码相同,请使用模板。否则,重载函数可能是要走的路。

以上是关于将由 boost::variant 聚合的类型的对象传递给接受该 boost::variant 的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何返回由 boost::variant 返回类型中包含的类型的子集组成的 boost::variant

boost::variant:递归向量类型的奇怪行为

使用 boost::mpl 获取 boost::variant 的类型索引

boost.variant 派生类型:不能使用复制构造函数

(C++, boost::variant) boost 变体映射的数据类型并对其执行数学运算

为啥我不能用 boost::variant 访问这个自定义类型?