Ошибка: невозможно связать неконстантную ссылку lvalue типа 'int &' с rvalue типа 'int' - PullRequest
0 голосов
/ 04 января 2019

Мне нужно создать объект Bar, который имеет закрытый объект Foo f.

Однако значение параметра объекта Foo должно передаваться определенным методом int genValue().

Если я инициализирую f в области видимости конструктора Bar(){...}, выкрикивается ошибка компилятора, что-то вроде того, что нет конструктора Foo().

Если я конструирую так Bar(): f(genValue()),компилятор выдает ошибку:

test.cpp: в конструкторе 'Bar :: Bar ()':

test.cpp: 16: 19: ошибка: невозможно связать неконстантныйlvalue ссылка типа 'int &' на rvalue типа 'int'

Bar (): f (genValue ()) {
~~~~~~~~ ^ ~

test.cpp: 7: 2: примечание: инициализация аргумента 1 'Foo :: Foo (int &)'
Foo (int & x) {
^ ~~

class Foo {
public:
    Foo(int &x) {
        this->x = x;
    }
private:
    int x;
};

class Bar {
public:
    Bar(): f(genValue()){
    }
private:
    Foo f;

    int genValue(){
        int x;
        // do something ...
        x = 1;
        return x;
    }
};

int main() {

    Bar bar ();

    return 0;
}

Как я могу исправить проблему, если я не хочу изменять Foo класс и значение его аргумента должно быть передано из genValue()?И я не хочу использовать чистый указатель (*), но решение с умным указателем в порядке!

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Не передавайте int&, оно не может быть привязано к константе или временно, потому что они не могут быть изменены - вместо этого используйте const int&.

На самом деле для простых типов вы должны предпочестьвместо этого передайте по значению и дайте оптимизатору побеспокоиться о предоставлении наилучшей реализации.

0 голосов
/ 04 января 2019

Не const опорный параметр, такой как int&, может ссылаться только на "lvalue", который является именованной переменной.

auto takes_nonconst_reference = [](int&){};
auto takes_const_reference = [](const int&){};
auto takes_value = [](int){};
auto returns_int = []{return 42;};

int foo = 1;

// OK
takes_nonconst_reference(foo);
takes_const_reference(foo);
takes_const_reference(returns_int());
takes_value(foo);
takes_value(returns_int());

// compilation error, value returned from a function is not a named variable
takes_nonconst_reference(returns_int());

Inв этом конкретном случае, поскольку ваш класс хранит копию параметра конструктора, вы должны передать его по значению (int, а не int& или const int&).

0 голосов
/ 04 января 2019

Ваш тип Foo является мусором, как написано.Это приводит к вашей ошибке.

Foo(int &x) {
    this->x = x;
}

нет (а) абсолютно никакой причины брать x по ссылке здесь, и (б) еще меньше причин, чтобы брать ее по не-1006 * ссылке.

Любое из следующих исправлений и Foo, и ваша ошибка.

Foo(int const&x) {
    this->x = x;
}
Foo(int const&x_in):x(x_in) {
}

Foo(int x) {
    this->x = x;
}
Foo(int x_in):x(x_in) {
}

и, если значение на самом деле не int, все же дешевое для перемещения:

Foo(int x) {
    this->x = std::move(x);
}
Foo(int x_in):x(std::move(x_in)) {
}

это 6 независимых решений вашей проблемы.

Для int я бы использовал # 4;для не- int # 6.

Исправлять это за пределами Foo - плохая идея, потому что вы получаете ошибку , потому что Foo написано неправильно.Остальная часть вашего кода в порядке, не нарушайте хороший код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...