Visual Studio 无法解决类和命名空间中重载的明确函数

Visual studio unable to resolve overloaded unambiguous function in class and namespace

本文关键字:重载 函数 命名空间 Studio 解决 Visual      更新时间:2023-10-16

>请参阅下面的代码

#include <iostream>
#include <string>
namespace stringhelper
{
std::string to_string(int n) { return "0"; } // ignore wrong implementation. simplified for example purpose
}
using stringhelper::to_string;
class TestClass
{
public:
std::string to_string() const { return "TestClass:" + to_string(m_value); }
private:
int m_value;
};
int main()
{
TestClass tc;
std::cout << tc.to_string();
}

如果TestClass没有实现函数to_string(),在TestClass内,它能够解析to_string(m_value)stringhelper::to_string(int)。但是,当 TestClass 实现函数 to_string(( 时,编译器无法将to_string(int)解析为stringhelper::to_string。 相反,它坚持/解析函数以TestClass::to_string并给出一个错误,该函数TestClass::to_string不接受 1 个参数。

为什么会这样?

环境:

Visual Studio 2008 Professional Edition 9.0.21022.8 RTM

配置:Win32

视窗 8

此行为不限于 Visual Studio 2008。如果在现代 Clang 实现中进行测试,您将看到相同的行为。如您所知,派生类中的函数不重写基类中的函数,但具有相同名称的函数将隐藏基类中同名的其他函数。

这里的"问题"是,通过使用using语句,您将一个名为to_string的函数引入到一个作用域中,当从类内部查看它时,该作用域本质上是与上述示例中发生的情况完全相同的受害者。

如果标准让你用this->foo()调用成员函数,这可能不是问题。但是,由于类中的函数调用被假定为类的一部分,并且只有在其他作用域中找不到时才

会出现此问题。由于您的类中有一个实现,因此它具有优先级并将使用。由于您想要一个将int作为参数的版本,因此将查找成员函数的重载版本,并且由于它不存在,因此会出现您看到的错误。

这就是为什么using namespace经常会引入可能难以理解的错误的部分原因。如果要确保在具有相同名称的函数的类中使用stringhelper::to_string实现,则必须显式。

例如,即使您保留using语句,这也将正常工作。

#include <iostream>
#include <string>
namespace stringhelper
{
std::string to_string(int n) { return "0"; } // ignore wrong implementation. simplified for example purpose
}
using stringhelper::to_string;
class TestClass
{
public:
std::string to_string() const { return "TestClass:" + stringhelper::to_string(m_value); }
private:
int m_value;
};
int main()
{
TestClass tc;
std::cout << tc.to_string();
}