C++ 无法从';无符号整数';至';无符号整数&';

C++ 无法从';无符号整数';至';无符号整数&';,c++,c++11,C++,C++11,我正在创建一个方法,该方法的一个参数要求引用一个无符号int,但我想在该参数上设置一个默认值。例如: #include <iostream> using namespace std; class A { public: void sender(); private: unsigned int score = 10; }; class B { public: void receiver(unsigned int & score); }; void

我正在创建一个方法,该方法的一个参数要求引用一个
无符号int
,但我想在该参数上设置一个默认值。例如:

#include <iostream>

using namespace std;

class A {
public:
    void sender();
private:
    unsigned int score = 10;
};

class B {
public:
    void receiver(unsigned int & score);
};

void A::sender() {
    cout << "Before: " << score << endl;
    B b;
    b.receiver(score);
    cout << "After: " << score << endl;
}

void B::receiver(unsigned int & score) {
    score = 100;
}

int main() {
    A a;
    a.sender();
    return 0;
}
编译器将返回:

错误:无法将“10u”从“unsigned int”转换为“unsigned int&”

现场演示:

值“10”不是参考-它是一个值。通过使用By引用参数,必须使用引用调用它。使用默认参数意味着您可以在不指定参数的情况下调用函数,编译器将使用默认参数

类似地,调用
b.receiver(10)无效,但是

int someInt = 10;
b.receiver(someInt);

有效。

您希望参数类型为
常量unsigned int&
。否则,您可能会做一些疯狂的事情,比如尝试分配
10=20
,这毫无意义


而这恰恰是你所做的。
score=100
行似乎不是您实际的意思。

您不能将literal1分配给非
常量
引用

有两种情况,其中一种适合您的情况:

您打算修改传递给
receiver()的参数。
如果是这种情况,则使用非常量引用(
unsigned int&score
而不使用默认参数。在向其传递文本或临时对象的情况下,将导致编译器错误

a.receiver(10);  // Error

上述考虑到你想修改这个参数没有任何意义(如果C++允许的话,你就看不到修改了)。 您只想以只读方式使用参数 只需使用普通的、非引用的、

unsigned int
,因为
const unsigned int&score
编写起来很麻烦。如果您确定某个对象的复制成本很高,那么这就是您应该使用参数a const reference的时间

更新:有些情况下,您希望修改某些内容,但某些内容可能存在,也可能不存在。在这种情况下,您可能希望使用一个非拥有的指针作为参数

   // Declaration
   void receiver(unsigned int* score = nullptr);

void B::receiver(unsigned int* score) {
    if(score) *score = 100;
}

...

a.receiver();    // Uses the default parameter

unsigned int x;
a.reciever(&x);
在这种情况下,当它指向某个(假定的)有效变量时,它只分配给
分数。指针一点也不坏

更新2:但是,由于函数重载可能会更好

void B::receiver() {
    // Do something else
}

void B::receiver(unsigned int& score) {
    score = 100;
}
在希望重载在不同参数上表现不同的情况下,应该使用此选项

但是,我还是更喜欢第一个非默认参数选项,而不是指针选项和重载选项,因为它要求调用方提供一个参数,这在通过函数修改某些内容时会更好

<强>更新3:您还应该考虑让函数返回值,而不是通过参数修改它。在不需要修改对象的当前状态的情况下,让函数返回值更直观。不过有一个警告是,调用方可能会忘记捕获(分配)返回值,如果您将该值用作某个资源ID来释放某些内容,这可能会很危险


一般来说,是一个临时对象


2.如果10被神奇地转化为100,那么宇宙可能会变成100;)

除非是const reference,否则不能有引用类型的默认参数。您希望发生什么?你实际上是想说
10=100
;为什么?如果你想让不同的函数做不同的事情,请使用重载,而不是默认参数。请看下面的答案:我冒昧地缩小了标题所暗示的范围…类型兼容性不是这里的问题。这正是我的想法,但整个问题是如何添加默认参数,修改参数是函数唯一能做的事情。我理解你的想法,我尊重你,但请阅读我上面的评论,并尝试理解我想要什么,如果不可能,我会理解并继续你写的方式,我的选项。@SH.0x90请参阅我的更新。这也许能回答你的问题。非常感谢@MarkGarcia。
void B::receiver() {
    // Do something else
}

void B::receiver(unsigned int& score) {
    score = 100;
}