C++ 编译器正在尝试从int初始化枚举类,但它应该在';T
我有一个类型的枚举类,需要一个“to_string”函数来输出类型名,所以我在自己的命名空间中编写了这个函数。问题是,该命名空间中的其他函数试图调用上的_字符串,例如int(实际上只是一个int,不打算成为枚举的一部分)正在查找自定义的to_字符串,并给出有关枚举无效初始化的错误 我知道我可以显式地调用std::to_string而不是to_string,但我认为有更好的方法。我做错了什么 示例代码是:C++ 编译器正在尝试从int初始化枚举类,但它应该在';T,c++,enums,C++,Enums,我有一个类型的枚举类,需要一个“to_string”函数来输出类型名,所以我在自己的命名空间中编写了这个函数。问题是,该命名空间中的其他函数试图调用上的_字符串,例如int(实际上只是一个int,不打算成为枚举的一部分)正在查找自定义的to_字符串,并给出有关枚举无效初始化的错误 我知道我可以显式地调用std::to_string而不是to_string,但我认为有更好的方法。我做错了什么 示例代码是: #include <iostream> #include <string&
#include <iostream>
#include <string>
namespace other {
enum class Type {
Type1,
Type2
};
std::string to_string(const Type& type) {
switch(type) {
case Type::Type1:
return "Type1";
break;
case Type::Type2:
return "Type2";
break;
default:
{}
}
return "Unknown";
}
void run() {
using namespace std;
cout << string("Type: ") + to_string(Type::Type1) << endl;
cout << string("int: " ) + to_string(42) << endl; // this one generates compile-time errors
}
}
int main() {
other::run();
using namespace std;
cout << string("int: " ) + to_string(42) << endl; // This one is ok
return 0;
}
#包括
#包括
名称空间其他{
枚举类类型{
类型1,
类型2
};
std::字符串到_字符串(常量类型和类型){
开关(类型){
案例类型::类型1:
返回“Type1”;
打破
案例类型::类型2:
返回“Type2”;
打破
违约:
{}
}
返回“未知”;
}
无效运行(){
使用名称空间std;
cout您需要明确指定要将什么函数引入“重载集”():
void run(){
使用名称空间std;
使用std::to_字符串;
CUT这是一个棘手的情况,涉及到一些细微的命名空间规则。让我们考虑一个简单的例子:
namespace b {
void f(int) { }
}
namespace a {
using namespace b;
void f(char) { }
void g()
{
f(5); // calls f(char)
}
}
这里的问题是,尽管我们使用了名称空间b
,但b中的声明被视为是在公共名称空间(全局)中声明的,以便查找:
(C++14.7.3.4/2)
using指令指定指定命名空间中的名称可以在
using指令出现在using指令之后。在非限定名称查找(3.4.1)过程中,名称将出现
就好像它们是在最近的封闭名称空间中声明的,该名称空间包含using指令和
指定名称空间[注意:在此上下文中,“包含”表示“直接或间接包含”。-结束
注]
因此,出于查找目的,命名空间b中的名称被视为全局命名空间中的名称。这意味着命名空间a中的f(char)
将隐藏命名空间b中的f(int)
:
(C++143.3.10/4)
在查找由命名空间名称限定的名称的过程中,可能会进行的声明
using指令可见的可以通过包含
使用指令;参见(3.4.3.2)
在您的示例中,在other::run()
中调用to_string(42)
将找到other::to_string
,因为std::to_string(int)
是隐藏的。为什么需要这样做?编译器不应该检测到从int到Type的转换无效,然后继续寻找另一个有效的签名吗(并以std::to_string结尾)?引入std::to_string
显式地使此方法在名称查找中更匹配。如果没有此方法,您将支付(粗略地说)对于命名空间层次结构中的每个步骤。通过导入,可以免费使用。很抱歉没有提供解释,我正试图找到一个好的源代码/标准部分来引用。因此,函数位于“lower”如果名称相同,名称空间将对更高级别的函数进行阴影处理?即使签名不同?编译器在尝试匹配签名时没有发现错误,然后继续进一步查找有效匹配,这有什么实际原因吗?@ryan0270:是的,在scop中进行重载工作被认为太混乱了es.这里更详细:只是我对事物的看法…如果你可以更具体一些,那么就这样做。例如,在你的run()
中,我会键入other::to_string
和std::to_string
,这样编辑它的下一个可怜的家伙就知道我的意图。好问题,我以前从未考虑过命名空间隐藏/重载。
namespace b {
void f(int) { }
}
namespace a {
using namespace b;
void f(char) { }
void g()
{
f(5); // calls f(char)
}
}