C++ 使用两个名称空间只能部分起作用
当我尝试编译此代码时:C++ 使用两个名称空间只能部分起作用,c++,enums,namespaces,C++,Enums,Namespaces,当我尝试编译此代码时: #include <iostream> namespace Direction { enum Enum { UP, DOWN, LEFT, RIGHT }; } using namespace std; void move(int pDir); int main() { printf("UP: %u\n", Direction::UP); printf("DOWN: %u\n", Direction::DOWN); pr
#include <iostream>
namespace Direction
{
enum Enum { UP, DOWN, LEFT, RIGHT };
}
using namespace std;
void move(int pDir);
int main()
{
printf("UP: %u\n", Direction::UP);
printf("DOWN: %u\n", Direction::DOWN);
printf("LEFT: %u\n", Direction::LEFT);
printf("RIGHT: %u\n", Direction::RIGHT);
move(Direction::UP);
return 0;
}
void move(int pDir)
{
printf("Move: ");
switch(pDir)
{
case(Direction::UP):
printf("UP");
break;
case(Direction::DOWN):
printf("DOWN");
break;
case(Direction::RIGHT):
printf("RIGHT");
break;
case(Direction::LEFT):
printf("LEFT");
break;
default:
printf("nothing");
break;
}
}
结果是:
UP: 0
DOWN: 1
LEFT: 2
RIGHT: 3
似乎void move(…)
只是被忽略了
我已经发现了问题:这是使用命名空间std的。当我删除它时,我得到了预期的结果
所以我有三个问题:
1) 为什么void move(…)
只是被“忽略”了
2) 为什么我可以访问int main()
3) 我怎样才能解决这个问题
祝我的朋友们过得愉快
ps:这是我问题的一个摘录示例,在我的项目中,我需要使用名称空间std
您的移动功能应用程序已经过审查,不幸的是
找到了更好的应用。请随时联系我们
征求意见或问题
是在这种情况下调用的函数。这是由多个因素造成的:
- iostream包含实用程序头,因此它在代码中定义
- 由于
使用命名空间std
,因此std命名空间中的任何函数定义都是无效的李>
- 参数
Direction::UP
为右值,std::move的签名为templateconstexpr typename std::remove\u reference::type&&move(T&&T)noexcept代码>。T可以解析为枚举类型而无需转换
- 你的是
无效移动(int-pDir)
和将需要从方向::Enum&
到int
的隐式转换
当您删除这些条件中的一个时,您的函数将被调用。比如说
move((int)Direction::UP);
消除隐式转换的需要。由于使用名称空间std
,move
(您的)和std::move
现在都可以通过名称move
访问,当您调用它时,通常会发生重载解析,因此编译器会检查
move(int)
或
template move(T)//此处简化了位
更适合您的通话移动(方向::向上)
。由于非作用域枚举的基础类型(akastd::undernative_type
)是实现定义的,因此它可以是char
或short
(或任何其他内容),在这种情况下,第二个候选项是更好的匹配项
其他因素(如UmNyobe提到的右值)和参数的名称空间也会对重载解析产生影响。例如,将move
的定义移动到Direction
名称空间应该会导致调用第一个候选者,因为ADL(参数相关查找)起作用,尽管我现在不能100%确定这一点
因此,正如其他人已经建议的那样,我的建议是尽量避免使用名称空间
,至少是在文件范围内。如果需要从一个名称空间访问大量内容,只需将using namespace
放入需要它的函数中即可。特别是关于名称空间std
,我强烈建议不要使用使用名称空间std
不确定这是否是问题所在,但至少这是一个混淆的来源:不要使用使用名称空间std代码>,还有std::move
,你知道当你写move
时它是哪一个吗?;)刚刚看到“我需要使用名称空间std”,但我不敢相信。你为什么要做这么可怕的事?@user463035818这正是问题所在。(好吧,再加上带有printf
s的UB)这是一个味道的问题,但我甚至不会这么做,一旦你使用std::move
,你就再也无法轻易发现std::move
或:move
(顺便说一句::move
可能会解决你的问题,但我一点也不确定)或者您可以只键入std::cout
。显式>隐式。这几个字符输入起来并不难。最后,如果在特定范围内大量使用::std
中的标识符,则应该使用std::identifier
来保存一些键入。但总的来说,要明确,帮助你未来的自己;)
move((int)Direction::UP);