超负荷的呼唤是暧昧的

Asm*_*zan 3 c++ overload-resolution c++14

我正在学习新的C++语义,我在这个程序中遇到错误:

#include <iostream>
#include <string>
#include <utility>

std::string foo(std::string str)
{
    return str + " call from normal";
}

std::string foo(const std::string& str)
{
    return str + " call from normal";
}

std::string foo(std::string&& str)
{
     return str + " call from ref ref";
}

int main()
{
    std::string str = "Hello World!";
    std::string res = foo(str);
    std::string&& res_ref = foo(std::move(str));
    std::cout << "Res ref = " << res_ref << std::endl;
    std::cout << "Str = " << str << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误是:

:23:30: error: call of overloaded ‘foo(std::__cxx11::string&)’ is ambiguous
    std::string res = foo(str);
Run Code Online (Sandbox Code Playgroud)

为什么电话不明确?

Bar*_*rry 6

当你有;

std::string res = foo(str);
Run Code Online (Sandbox Code Playgroud)

有两个可行的候选人:

foo(std::string );         // #1
foo(std::string const& );  // #2
Run Code Online (Sandbox Code Playgroud)

在给定多个候选者时,确定选择哪个功能有许多很多步骤.但在这种情况下,两种选择都完全无法区分 - 在参数之间stringstring const&参数之间的重载决策中根本没有偏好.同样,也没有偏爱stringstring&&一个右值参数,因此你的第二个电话也被认为是不明确的.

一般来说,对于喜欢一个功能到另一个规则都与哪一个更具体.例如,给定一个函数取string&和一个取string const&,前者只能用非const左值引用来string调用,但后者可以用一大堆东西调用,所以当两者都可行时,前者是首选的(具体来说) ,由于[over.ics.rank] /3.2.6).但在这种情况下,您可以打电话给任何人,你可以打电话#1#2.你可以打电话给任何东西#2,你可以打电话#1.所以没有任何理由更喜欢一个到另一个.

你应该简单地删除那个重载,留下你的两个:

foo(std::string const& ); // #2
foo(std::string&& );      // #3
Run Code Online (Sandbox Code Playgroud)

对于左值std::string,只有#2是可行的.对于rvalue std::string,两者都是可行的,但#3将是首选(根据一般准则,它更具体 - 特别是由于[over.ics.rank] /3.2.3).