错误:无法将类型为'int&'的非常量左值引用绑定至类型为'int'的右值

时间:2019-01-04 04:00:22

标签: c++ class constructor

我需要创建一个Bar对象,其中有一个私有对象Foo f

但是,Foo对象参数的值应由特定方法int genValue()传递。

如果我在构造函数作用域f中初始化Bar(){...},则会引起编译器大喊错误,就像没有构造函数Foo()一样。

如果我这样构造Bar(): f(genValue()),则编译器会大喊错误:

  

test.cpp:在构造函数“ Bar :: Bar()”中:

     

test.cpp:16:19:错误:无法将类型为'int&'的非常量左值引用绑定至类型为'int'的右值

     

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

     

test.cpp:7:2:注意:初始化“ Foo :: Foo(int&)”的参数1
   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 :(得分:1)

您所写的Foo类型是垃圾。这会导致您的错误。

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

(a)这里绝对没有理由引用x,而(b)更少理由引用非const

以下任何一项都可以修复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错误而出错。您其余的代码很好,请避免破坏好的代码。

答案 1 :(得分:1)

不要传递int&,它不能绑定到常量或临时对象,因为它们不能被修改-请改用const int&

实际上,对于简单类型,您应该更喜欢按值传递,而让优化器担心提供最佳实现。

答案 2 :(得分:1)

非{const的引用参数(例如int&)只能引用“左值”,这是一个以命名的变量。

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

在这种情况下,由于您的类存储了构造函数参数的副本,因此应按值(intint&const int&)传递它。