【问题标题】:could not convert from 'unsigned int' to 'unsigned int&'无法从 'unsigned int' 转换为 'unsigned int&'
【发布时间】:2014-04-05 11:25:26
【问题描述】:

我正在创建一个方法,该方法的一个参数要求引用unsigned 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;
}

现场演示:in here

当我这样做时会发生错误:

void receiver(unsigned int & score = 10u);

编译器返回:

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

现场演示:in here

【问题讨论】:

  • 你不能有引用类型的默认参数,除非它是 const 引用
  • 你想要发生什么?你本质上是想说10 = 100;为什么?
  • 如果你想要不同的函数做不同的事情,使用重载,而不是默认参数。
  • 我冒昧地缩小了标题所暗示的范围……类型兼容性不是这里的问题。

标签: c++ c++11


【解决方案1】:

您不能将文字1 分配给非const 引用。

有两种情况适合您的情况:

您打算修改传递给receiver() 的参数

如果是这种情况,请使用非常量引用 (unsigned int &amp; score)不带默认参数。如果您将文字或临时对象传递给它,则会导致编译器错误。

a.receiver(10);  // Error

考虑到您要修改该参数,上述内容没有多大意义(如果 C++ 允许,您将看不到修改2)。

您打算只以只读方式使用该参数

只需使用普通的、非引用的unsigned int,因为const unsigned int&amp; score 写起来很痛苦。如果您确定一个对象的复制成本很高,那么您应该将参数作为 const 引用。

更新:某些种情况下,您想要修改某些内容,但某些内容可能存在也可能不存在。在这种情况下,您可能希望使用 non-owning 指针作为参数。

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

在这种情况下,它仅在指向某个(假定的)有效变量时分配给score。指针一点也不差。

更新 2: 然而,作为@Potatoswatter have pointed out,你最好还是使用函数重载。

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

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

如果您希望重载在不同参数上表现不同,则应使用此选项。

不过,我更喜欢第一个非默认参数选项,而不是指针选项和重载选项,因为它要求调用者提供参数,当您正在通过函数修改某些内容。

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


1 通常是一个临时对象。

2如果 10 神奇地变成 100,宇宙可能会blow up ;)

【讨论】:

  • 这些正是我的想法,但整个问题是如何添加默认参数,而修改参数是该函数唯一所做的事情。
  • 我理解你的想法,我尊重,但请阅读我上面的评论并尝试理解我想要什么,如果不可能,我会理解并继续你写的方式,我的选择。跨度>
  • @SH.0x90 查看我的更新。这可能会回答你的问题。
  • 非常感谢@MarkGarcia。
【解决方案2】:

您希望参数类型为const unsigned int&amp;。否则,你可以做一些疯狂的事情,比如尝试分配10 = 20,这是没有意义的。

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

【讨论】:

    【解决方案3】:

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

    同样,调用b.receiver(10); 无效,但是

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

    有效。

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      相关资源
      最近更新 更多