【问题标题】:Problem with passing by reference通过引用传递的问题
【发布时间】:2011-03-14 17:38:41
【问题描述】:

我可以重载一个接受引用或变量名的函数吗?

例如,当我尝试这样做时:

void function(double a);
void function(double &a);

我希望这个函数的调用者能够做到:

double a = 2.5;
function(a); // should call function(double &a)
function(2.3); // should call function(double a)

我想编写传递引用函数以更好地使用内存并可能在范围外操作变量,但不必为了调用函数而创建新变量。

这可能吗?

干杯

【问题讨论】:

  • 我认为这通常是可能的,尽管在您的示例中,两者都会调用function(double a),因为 a 是一个 int,并且不能作为对 double 的引用。
  • 抱歉,意思是说 a 是双精度数。现已更正问题
  • “可能在范围外对变量进行操作”是什么意思,以及如何与function(2.3) 一起工作

标签: c++ pass-by-reference overloading pass-by-value


【解决方案1】:

我认为你在这里忽略了重点。你真正应该拥有的只是这个:

void function(const double &a);

注意“常量”。有了这个,你应该总是得到传递引用。如果您有非常量的按引用传递,那么编译器将正确地假定您希望修改传递的对象——这当然在概念上与按值传递变体不兼容。

使用 const 引用,编译器会很乐意在您背后为您创建临时对象。非 const 版本不适合你,因为编译器只能将这些临时对象创建为“const”对象。

【讨论】:

  • CAVEAT:如果“function”不能被内联,那么“const double&”可能会更昂贵,因为它将“a”强制进入内存。如果参数模式是按值,大多数编译器将在寄存器中传递双精度值。
  • 确实如此。 C++ 中的约定通常是通过值传递内置类型(int、double、char、指针等),通过引用传递复合类型(类和结构)。
  • @泰勒,路德。你当然是对的。我假设“double”的选择只是一种选择作为(略差)示例的类型......
【解决方案2】:

我试过了,失败了

至少在 MSVC2008 中,这是不可能的 - 我认为这适用于所有 c++ - 编译器。

定义本身是有效的,但是在尝试调用函数时

function(a);

使用变量作为参数,由于编译器无法决定使用哪个函数而引发编译器错误。

【讨论】:

    【解决方案3】:
    void function(double const &a);  // instead of void function(double a);
    void function(double       &a); 
    

    【讨论】:

      【解决方案4】:

      我不认为定义:

      void function(double a);
      void function(double &a);
      

      是可能的...编译器如何知道为function(x) 调用哪个函数? 如果你想同时使用引用和值,你应该使用两个不同的函数。这也将使代码比这种模棱两可的重载更容易阅读。

      【讨论】:

      • 我认为这是可能的,如果可能的话,参考版本将是首选。不过,没有任何证据支持这种说法。
      • gcc 4.1.2:错误:重载的“函数(int&)”的调用不明确
      • @roe - 定义本身是可能的。但是,由于重载解析不明确,您将无法调用参考版本。标准中没有任何内容使参考版本更可取。可以使用 const 或 rvalue 参数调用非引用版本。
      【解决方案5】:

      通过引用传递 POD 类型没有任何好处,因为它们几乎总是(总是?)在注册表中传递。 通过 const 引用传递的复杂类型(由多个 POD 变量组成的类型)通常(总是?:D)是一种优于复制和堆栈推送的方式。 您甚至可以通过创建 explicit constructors 来控制从 POD 类型创建复杂类型变量的临时变量

      【讨论】:

        【解决方案6】:

        不,您不能这样做,因为这两个函数都会有效地产生相同的错位名称,并且链接器将无法解析函数调用。

        【讨论】:

        • 嗯。不会。引用参数不会产生与普通参数(复制参数)相同的名称重整。这相当于说指向双精度的指针和双精度参数都会产生相同的名称修饰。
        猜你喜欢
        • 2015-08-09
        • 2018-02-13
        • 2012-09-06
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多