基于值与Const参考的函数重载

kir*_*kun 28 c++ overloading pass-by-reference pass-by-value

声明如下的内容

void foo(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }
Run Code Online (Sandbox Code Playgroud)

有意义吗?调用者如何能够区分它们?我试过了

foo(9);  // Compiler complains ambiguous call.

int x = 9;
foo(x);  // Also ambiguous.

const int &y = x;
foo(y);  // Also ambiguous.
Run Code Online (Sandbox Code Playgroud)

Ale*_*ler 11

意图似乎是在调用与临时(即9)和"常规"参数传递之间进行区分.第一种情况可能允许函数实现采用优化,因为很明显参数将在之后处理(这对于整数文字来说绝对没有意义,但对于用户定义的对象可能是有意义的).

但是,当前的C++语言标准没有提供专门为参数的'l/r-valueness'重载的方法 - 任何作为参数传递给函数的l值都可以隐式转换为引用,因此歧义是不可避免的.

C++ 11引入了一个类似用途的新工具 - 使用r值引用,您可以按如下方式重载

void foo(int x)        { ... }
void foo(const int &&x) { ... }
Run Code Online (Sandbox Code Playgroud)

...和foo(4)(作为参数传递的临时r值)将导致编译器选择第二个重载,同时int i = 2; foo(i)选择第一个.

(注意:即使使用新的工具链,也无法区分样品中的情况2和3!)

  • 对于rvalues,`const int &&`仍然与`int`无法区分. (7认同)

Inv*_*rse 6

你可以用一个模板来做到这一点:

template<typename T> void foo(T x) { ... }

然后你可以通过值或引用调用这个模板:

int x = 123;
foo<int>(x);  // by value
foo<int const&>(x);  // by refernce
Run Code Online (Sandbox Code Playgroud)