5

考虑以下函数原型:

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

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

第二个是按照第一个来执行的。也就是说,除了一个是按引用传递而另一个是按值传递之外,它们在各个方面在功能上都是相同的。

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

Remove(SomeContainer, 123);

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

4

4 回答 4

5

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

  1. 论据数
  2. 论据类型 &
  3. 论证顺序

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

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

void doSomething(int i)
{
}

void doSomething(int &i)
{
}

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

在这里,编译器无法确定传递val给哪个版本的doSomething(). 它可以对任何版本进行有效的函数调用,因此它在编译时寻求帮助(因为这是静态链接)并将调用标记为模棱两可。

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

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

于 2011-05-02T12:51:08.973 回答
3

如前所述,不考虑返回类型进行重载。但是,编译器确实会考虑纯值并引用不同的类型,但它通常不知道要调用哪个版本。换句话说,拥有两个仅在参数是按值传递还是按引用传递方面不同的重载函数在您尝试调用它之前都很好:潜在的歧义不是 C++ 中的错误。

例子:

void f(int) {
    cout << "value\n";
}

void f(int&) {
    cout << "reference\n";
}

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++ 重载的工作原理。

于 2011-05-02T13:06:42.823 回答
2

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

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

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

于 2011-05-02T13:04:52.353 回答
1

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

于 2011-05-02T12:56:08.067 回答