在没有歧义的情况下是否允许通过引用重载函数?
Is function overloading by reference allowed when there is no ambiguity?
考虑以下代码:
#include <iostream>
void foo(int m);
void foo(int &k);
int main()
{
foo(5); // ok, because there is no ambiguity
int m = 5;
//foo(m); // compile-time error, because of ambiguity
foo(m + 0); // ok, because it's an expression of type int and not object's lvalue
}
void foo(int m)
{
std::cout << "by value\n";
}
void foo(int &k)
{
std::cout << "by reference\n";
}
我知道它为 foo(m)
引入了歧义,但是当表达式是 int
类型(或另一个可以转换为 int
的类型)时,这是否允许?
我试图找到一些关于此的标准参考,但没有成功。
免责声明:请注意,它不是 Function Overloading Based on Value vs. Const Reference 的重复。 const
引用不同,因为它们可以用 rvalues 赋值,与 "ordinary" 相反,非 const
参考.
可以,允许。
没有防止这种过载的规则。
[C++14: 13.1/1]:
Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. [..]
[C++14: 13.1/2]:
(blah blah lots of exceptions not including any for this case)
如果语言禁止函数重载,可能在某些情况下使用某些调用会模棱两可,我可能会无缘无故地添加!
13.1 [over.load] 非常清楚(除了多页注释)哪些函数不能在同一范围内重载。
你的案例没有在那里列出,你可以声明那些重载,但你不一定能轻易使用它们。你可以这样称呼左值:
void (*f)(int&) = foo;
f(m);
这避免了调用 foo(m)
时发生的歧义。
旁白:foo(m + 0)
的另一种写法是 foo(+m)
,一元运算符 +
将左值转换为右值,因此调用了 foo(int)
重载。
考虑以下代码:
#include <iostream>
void foo(int m);
void foo(int &k);
int main()
{
foo(5); // ok, because there is no ambiguity
int m = 5;
//foo(m); // compile-time error, because of ambiguity
foo(m + 0); // ok, because it's an expression of type int and not object's lvalue
}
void foo(int m)
{
std::cout << "by value\n";
}
void foo(int &k)
{
std::cout << "by reference\n";
}
我知道它为 foo(m)
引入了歧义,但是当表达式是 int
类型(或另一个可以转换为 int
的类型)时,这是否允许?
我试图找到一些关于此的标准参考,但没有成功。
免责声明:请注意,它不是 Function Overloading Based on Value vs. Const Reference 的重复。 const
引用不同,因为它们可以用 rvalues 赋值,与 "ordinary" 相反,非 const
参考.
可以,允许。
没有防止这种过载的规则。
[C++14: 13.1/1]:
Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. [..]
[C++14: 13.1/2]:
(blah blah lots of exceptions not including any for this case)
如果语言禁止函数重载,可能在某些情况下使用某些调用会模棱两可,我可能会无缘无故地添加!
13.1 [over.load] 非常清楚(除了多页注释)哪些函数不能在同一范围内重载。
你的案例没有在那里列出,你可以声明那些重载,但你不一定能轻易使用它们。你可以这样称呼左值:
void (*f)(int&) = foo;
f(m);
这避免了调用 foo(m)
时发生的歧义。
旁白:foo(m + 0)
的另一种写法是 foo(+m)
,一元运算符 +
将左值转换为右值,因此调用了 foo(int)
重载。