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)//此处简化了位

更适合您的通话
移动(方向::向上)
。由于非作用域枚举的基础类型(aka
std::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);