【问题标题】:Why is this allowed?为什么允许这样做?
【发布时间】:2014-03-21 00:33:40
【问题描述】:

所以我知道不允许有具有相同参数和名称的函数:

int a(int b) {
    return b;
}
int a(int b) {
    return b;
}

int main() {
    int c = a(4);
}

上面的这个不会编译。但后来我开始想,如果我通过引用传递一个,然后通过值传递一个呢?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
}

上面确实编译,我猜是因为你不能通过引用传递4,所以它假设你想要第一个a,这意味着编译器可以区分你要调用哪个函数。如果我然后将main 更改为:

int main() {
    int c = a(4);
    a(c);
}

它将无法编译,我假设因为c 可以传递给任一函数,所以编译器不知道要调用哪个函数。

但是……这个呢?

int a(const int& b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}

这确实编译。为什么?我预计不会,因为c 可以同时传递给第一个和第二个a。我有什么误解吗?

我的具体问题是,为什么这个(下面的代码)不能编译,而最后一个可以?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}

如果我是编译器,我可以根据参数匹配的接近程度来选择调用哪个函数,对于调用a(c),我可以从第一个和第二个中进行选择。在这个例子中,第一个或第二个a 有什么原因不能选择?

【问题讨论】:

  • 其中一个是完美的匹配;另一个不是。
  • @chris 所以编译器只是猜测?
  • 不,它使用完美匹配。
  • @chris 好的,我明白了。但是为什么第二个代码块(带有修改的 main)不能编译?因为有两个完美的匹配?究竟什么才是完美匹配?
  • @BWG,STL 在这个主题上做了一个很棒的视频。 Here you go!

标签: c++ reference constants overloading


【解决方案1】:

从函数调用中选择要使用的正确函数的过程称为重载解决。当调用一个函数时,编译器会搜索所有具有该名称的函数(重载)并将它们编译成一个重载集。简而言之,通过从参数中选择需要最少转换的函数来选择最佳匹配。

这是编译器从a(c) 中选择的两个函数:

int a(const int& b);
int a(      int& b);

选择第二个重载是因为第一个重载需要const-qualification。您调用函数时使用的变量c 不是const,因此它是第二个重载 的完美匹配,并且可以绑定到非const 引用.

【讨论】:

    【解决方案2】:
    int a(const int& b) {
        return b;
    }
    int a(int& b) {
        return b;
    }
    
    int main() {
        int c = a(4);
        a(c);
    }
    

    当你用a(4) 调用它时,4 是一个文字,只有你使用const reference 的版本才能绑定它,所以这就是被调用的那个。

    现在,当您调用a(c) 时,您将c 作为非常量 int,因此它会更喜欢采用非常量 引用的函数。

    【讨论】:

      猜你喜欢
      • 2011-08-17
      • 2011-10-14
      • 2013-09-07
      • 1970-01-01
      • 2020-05-01
      • 2017-02-24
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      相关资源
      最近更新 更多