错误:无法将“int&”类型的非常量左值引用绑定到“int”类型的右值

eri*_*hsu 12 c++ constructor class

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

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

如果我f在构造函数范围内初始化 Bar(){...},编译器会大喊错误,就像没有构造函数一样Foo()

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

test.cpp: In constructor ‘Bar::Bar()’:
test.cpp:16:19: error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
 Bar(): f(genValue()){    
            ~~~~~~~~^~
test.cpp:7:2: note:   initializing argument 1 of ‘Foo::Foo(int&)’    
 Foo(int &x) {    
 ^~~
Run Code Online (Sandbox Code Playgroud)

示例代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

如果我不想修改Foo类并且它的参数值应该从 传递,我该如何解决这个问题genValue()?而且,我不想使用纯指针 (*),但是使用智能指针的解决方案是可以的!

Mar*_*som 14

不要传递int&,它不能绑定到常量或临时变量,因为它们无法修改 - 请使用const int&

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


Ray*_*mel 8

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());
Run Code Online (Sandbox Code Playgroud)

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

  • 深入了解各种价值类别的所有细节对初学者一点帮助都没有,只会让人感到困惑和沮丧。“左值是命名变量,右值是临时变量”对于初学者来说是一个足够好的启发式方法,对于英语来说,“I 之前的 E 之前,除了 C 之后”没有更多的“过度简化”。 (3认同)
  • 另外,如果我们迂腐,某些左值没有存储位置,例如非类型模板参数和 `[[no_unique_address]]` 空数据成员。 (2认同)