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

假设我有:

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&”类型的引用初始化无效 “TypeA”类型的表达式

  3. 这也不编译:

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

    出现错误:

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

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

非常感谢!

【问题讨论】:

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


    【解决方案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?
    • 模板不关心实际的参数类型。唯一重要的是,您对类型参数化对象执行的任何操作都对实际类型的对象有效。如果两种类型的代码相同,请使用模板。否则,重载函数可能是要走的路。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多