函数的不明确的引用/值版本

发布于 2024-11-04 17:50:53 字数 390 浏览 1 评论 0原文

考虑以下函数原型:

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

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

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

然而,GCC 表示,在这种情况下,这些内容是不明确的,即使第一个表单是唯一不返回值的表单:

Remove(SomeContainer, 123);

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

Consider the following function prototypes:

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

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

The second is implemented in terms of the first. That is to say, they are functionally identical in every way except that one is pass-by-reference and the other is pass-by-value.

However, GCC says these are ambiguous in cases like this, even though the first form is the only one that does not return a value:

Remove(SomeContainer, 123);

Is there any workaround to this, or do I have to come up with different names for each form?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

对岸观火 2024-11-11 17:50:53

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

  1. 参数数量
  2. 参数类型和参数类型
  3. 参数序列

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

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

void doSomething(int i)
{
}

void doSomething(int &i)
{
}

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

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

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

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

Return type is not an basis of function overloading.
Overloading of functions can only be with one of the following criteria:

  1. No of arguments
  2. Type of arguments &
  3. Sequence of arguments

The return type can be ignored by the caller and hence it is not a valid criteria for function overloading.

Having said the above, pass by value and passing a Reference will create a ambiguity to the compiler. For eg:

void doSomething(int i)
{
}

void doSomething(int &i)
{
}

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

Here the compiler cannot determine as to pass val to which version of doSomething(). It can make a valid function call to any of the versions, so it cries out for help at compile time(since this is static linking) and flags the calls as ambiguous.

In case such as yours. It is a choice/preference as to rename the functions or pass pointer argument which will make the two functions overloaded(same name but different argument types). However, it is important to take in to account the requirement & the action the function is going to perform while choosing the preference. Personally, I wouldn't choose a pointer just for sake of overloading. If I do need to reseat or make my argument point to different variables then it would make sense to choose pointer argument.

Simple way is to just have two distinct function names. There is no overhead and it is just as efficient as any other function call.

在巴黎塔顶看东京樱花 2024-11-11 17:50:53

如前所述,返回类型不考虑重载。然而,编译器确实考虑纯值并引用不同的类型,但它通常不知道要调用哪个版本。换句话说,拥有两个仅在参数是按值传递还是按引用传递方面不同的重载函数是可以的,直到您尝试调用它:潜在的歧义在 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++ 重载的工作原理。

As mentioned, the return type is not considered for overloading. However, the compiler does consider plain-value and references different types, but it will normally not know which version to call. In other words, having two overloaded functions that are different only in whether a parameter is pass-by-value or pass-by-reference is fine up until you try to call it: Potential ambiguity is not an error in C++.

Example:

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"
}

I do not know how to signal that you want f(int&), however, so there is not much practical use in this -- I'm just trying to clarify how C++ overloading works.

我不会写诗 2024-11-11 17:50:53

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

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

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

You could help the compiler a bit, and the users of your functions, by choosing more distinguishing names:

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

Adding const to the immutable version will also inhibit users from accidentally calling the imperative variant (the compiler won't allow it, at least not for const containers).

ˉ厌 2024-11-11 17:50:53

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

Pass by reference/value is not used to determine function overloading because there is no way of the compiler knowing which is required - both are equally good matches for a value passed as a parameter. And as others point out, return type is never considered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文