2011-02-23 48 views
2

假设我有:路过一个boost ::变种的功能聚合的类型的对象,接受的boost ::变种

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); 
    } 
    

    与错误:

    invalid initialization of reference of type ‘Type&’ from expression of type ‘TypeA’

  3. 而且这并不编译:

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

    与错误:

    cannot convert ‘TypeA*’ to ‘Type*’ for argument ‘1’ to ‘void foo(Type*)’

有没有办法传递给接受升压功能:: variant是通过引用(如情况2)或指针(如情况3)由该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__); 

有两种解决方法(对于非模板富):

  • 转换为Type,然后取一个指针/引用这个
  • 创建boost::variant<TypeA*,TypeB*>的隐式转换踢

第三个解决方案是改变Foo自己,并使其模板。这取决于你想要做什么。

+0

谢谢!但是,__temporary__'是什么意思?如果你的意思是一个编译器的临时对象,是不是只能通过调用eg来创建它。 “富(类型A());” ?在你的第一个解决方案中,从TypeA到Type的转换是否需要拷贝,例如。如“TypeA a; Type t = a; foo(&t);”?很好你的第二个解决方案,我会考虑一下!关于模板,我怎样才能适应TypeA和TypeB,它们与无共同基类无关? – 2011-02-23 14:38:34

+0

@ Francesco:编译器将'a'复制到'Type'类型的临时对象(变体)中,然后使用这个临时对象执行对'foo'的调用。//模板只用于不相关的类型,只要需要的方法都存在于两者中。 – 2011-02-23 15:30:00

1

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

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

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

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

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

或重载函数:

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

谢谢!重载函数可能是一个解决方案。至于模板,我怎么能适应TypeA和TypeB,它们与没有共同的基类无关? – 2011-02-23 14:40:11

+0

模板不关心实际的参数类型。唯一重要的是,对类型参数化对象执行的任何操作对于实际类型的对象都是有效的。如果两种类型的代码相同,则使用模板。否则,重载函数可能是一条可行的路。 – Ferruccio 2011-02-23 14:59:19

+0

我明白了,谢谢。 – 2011-02-23 15:47:32

相关问题