函数的模糊引用/值版本

Ambiguous Reference/Value Versions of Functions

本文关键字:版本 引用 模糊 函数      更新时间:2023-10-16

考虑以下函数原型:

void Remove(SomeContainer& Vec, const std::size_t Index);
SomeContainer Remove(SomeContainer Vec, const std::size_t Index);

第二个是根据第一个实现的。也就是说,除了一个是按引用传递,另一个是按值传递之外,它们在各方面都是功能相同的。

然而,GCC说在这种情况下这些是不明确的,即使第一种形式是唯一不返回值的:

Remove(SomeContainer, 123);

是否有任何解决这个问题的方法,或者我是否必须为每个表单提出不同的名称?

返回类型不是函数重载的基础。
函数的重载只能满足以下条件之一:

  1. 参数个数
  2. 参数类型&
  3. 参数序列

返回类型可以被调用者忽略,因此它不是函数重载的有效标准。

如上所述,按值传递和传递引用会给编译器造成歧义。如:

void doSomething(int i)
{
}
void doSomething(int &i)
{
}
int main()
{
    int val = 10;
    doSomething(val);   //Ambiguous
}

这里编译器不能确定将val传递给哪个版本的doSomething()。它可以对任何版本进行有效的函数调用,因此它会在编译时请求帮助(因为这是静态链接),并将调用标记为二义性。

如果像你这样。重命名函数或传递指针参数将使两个函数重载(名称相同但参数类型不同)是一种选择/偏好。然而,考虑到需求是很重要的。函数在选择首选项时将要执行的动作。就我个人而言,我不会仅仅为了重载而选择指针。如果我确实需要重置或使我的参数指向不同的变量,那么选择指针参数是有意义的。

简单的方法是只使用两个不同的函数名。它没有开销,而且和其他函数调用一样高效。

如前所述,返回类型不考虑重载。然而,编译器确实会考虑纯值和引用不同的类型,但它通常不知道调用哪个版本。换句话说,两个重载函数的不同之处在于参数是按值传递还是按引用传递,直到您尝试调用它时才会出现问题:在c++中,潜在的歧义不是错误。

的例子:

void f(int) {
    cout << "valuen";
}
void f(int&) {
    cout << "referencen";
}
int main() {
    int  val = 42;
    f(val); // Error! Ambiguous.
    f(static_cast<int>(val)); // OK: The type is int. Will print "value"
}

我不知道如何表示你想要f(int&),但是,所以在这方面没有太多的实际用途-我只是想澄清c++重载是如何工作的。

您可以通过选择更有区别的名称来帮助编译器和函数的用户:

Container Removed( const Container& c, size_t index );
void Remove( Container& c, size_t index );

const添加到不可变版本还将阻止用户意外调用命令式变体(编译器不允许,至少对const容器不允许)。

按引用/值传递不用于确定函数重载,因为编译器无法知道哪个是必需的——对于作为参数传递的值,两者都是同样好的匹配。而且正如其他人指出的那样,从来没有考虑过返回类型。