Передать объект типа, агрегированного boost :: variable, в функцию, которая принимает этот boost :: variable - PullRequest
2 голосов
/ 23 февраля 2011

Предположим, у меня есть:

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

    с ошибкой:

    не может преобразовать 'TypeA *' в 'Type *' для аргумента '1' в 'void foo (Type *) '

Есть ли способ передать функции, которая принимает boost :: variable, экземпляр одного из типов, агрегированных этим boost :: variable, либо черезссылка (как в случае 2) или указатель (как в случае 3)?

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 23 февраля 2011

Что на самом деле происходит в 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 и сделать его шаблоном. Это зависит от того, что вы хотите сделать.

1 голос
/ 23 февраля 2011

Агрегация подразумевает, что boost::variant содержит как TypeA, так и TypeB. Это не так. Он содержит либо TypeA, либо TypeB. Это больше похоже на объединение, чем на структуру.

Вы можете передать TypeA по значению, поскольку существует неявное преобразование из TypeA в Type.

Не существует неявного преобразования из 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) {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...