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

时间:2011-02-23 13:10:44

标签: c++ pass-by-reference boost-variant

假设我有:

class TypeA { };
class TypeB { };
typedef boost::variant<TypeA, TypeB> Type;
  1. 没关系:

    void foo(Type t) { };
    
    int main(){
        TypeA a;
        foo(a);
    }
    
  2. 这不编译:

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

    错误:

      

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

  3. 这也不能编译:

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

    错误:

      

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

  4. 有没有办法传递给一个接受boost :: variant的函数的函数,该函数由boost :: variant聚合的一个类型的实例,通过引用(如情况2)或指针(如案例3)?

    非常感谢!

2 个答案:

答案 0 :(得分:1)

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

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

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

在不知道foo()TypeA / TypeB是什么的情况下,我无法向您提供更具体的建议,但也许您可以使用功能模板。即。

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

或重载函数:

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

答案 1 :(得分: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<TypeA*,TypeB*>进行隐式转换以启用

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