【问题标题】:Why a different type variable can be used as an argument of a parameter of const reference parameter in C++为什么不同类型的变量可以用作 C++ 中 const 引用参数的参数的参数
【发布时间】:2018-02-06 16:12:55
【问题描述】:
void foo(const int& v) {
    int x = v;
    std::cout << x;
}

int main()
{
    unsigned y = 1;
    foo(y);
}

在 C++ 中通过 y 代替 const int&amp; 合法

【问题讨论】:

  • 不要将代码 sn-p 用于 html/css/javascript 以外的内容。

标签: c++ pass-by-reference


【解决方案1】:

有两个因素可以让您的代码正常工作。首先,如果允许函数参数匹配重载,则最多允许函数参数进行一次隐式转换。其次,const 引用可以绑定到临时对象。这里发生的是y 隐式转换为int,创建一个临时副本。 v 然后绑定到那个临时的。

考虑以下示例:

#include <iostream>

void foo(const unsigned int & v) {
    std::cout << &v << '\n';
}

void bar(const int & v) {
    std::cout << &v << '\n';
}

int main()
{
    unsigned int y = 1;
    std::cout << &y << '\n';
    foo(y);
    bar(y);
    return 0;
}

您会发现foo(y) 打印的地址与y 相同,而bar(y) 打印的地址不同。这不适用于非const 引用。值得注意的是,如果可以的话,这意味着更改 v 可能实际上不会更改 y

【讨论】:

  • 我认为在这种情况下,隐式转换弊大于利。我想知道为什么语言被设计成允许这样做?
  • @xiaofengz 大多数隐式转换都继承自早期的c。与我交谈过的大多数开发人员都同意我的观点,即没有它们我们会更好,但为了兼容性而保留它们。 c++ 删除了一些更危险的转换,例如 void* 到其他指针类型和字符串文字到 char*。强类型枚举是 c++ 尽可能远离 c 的隐式转换的另一个例子。
【解决方案2】:

是的,这可能很烦人。由于在调用站点将y 隐式转换为匿名临时int,编译通过,并且允许const int&amp; 绑定。

你可以通过写作来解决这个问题

void foo(unsigned v) = delete;

甚至

template<typename Y> void foo(Y v) = delete;

所以所有重载除了你明确给出的重载都被删除。

【讨论】:

  • 如果我想依赖编译器来匹配类型,我将不得不“删除”所有可能的转换。感觉不是一个可行的解决方案。
  • @xiaofengz:我们已经解决了这个问题:使用模板。
猜你喜欢
  • 2021-05-29
  • 1970-01-01
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2014-10-14
相关资源
最近更新 更多