Использование двух пространств имен работает только частично - PullRequest
0 голосов
/ 15 мая 2018

Когда я пытаюсь скомпилировать этот код:

#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
Move: UP

Вместо этого будет:

UP: 0
DOWN: 1
LEFT: 2
RIGHT: 3

Кажется, что void move(..) просто игнорируется.

Я уже нашел проблему: это using namespace std.Когда я его удаляю, я получаю ожидаемый результат.

Итак, у меня есть три вопроса:

1) Почему void move(..) просто "игнорируется"

2)Почему я могу получить доступ к членам Direction в первых четырех строках int main()

3) Как это исправить?, _,

Хорошего дня, друзья мои.

ps: Это извлеченный пример моей проблемы, в моем проекте мне нужно использовать пространство имен std.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Из-за того, что ваши using namespace std и move (ваши), и std::move теперь доступны через имя move, и при его вызове происходит обычное разрешение перегрузки, поэтому компилятор проверяет, является ли

move(int)

или

template<typename T> move(T) // bit simplified here

лучше подходит для вашего звонка move(Direction::UP).Поскольку базовый тип (aka std::underlying_type) перечисления с незаданной областью определяется реализацией, это может быть char или short (или что-то еще), и в этом случае второй кандидат является лучшим соответствием.

Другие факторы (например, rvalue-ness, упомянутые UmNyobe) и пространство имен аргументов также могут влиять на разрешение перегрузки.Например, перемещение определения вашего move в пространство имен Direction должно привести к вызову первого кандидата, так как ADL (зависимый от аргумента поиск) начинает работать, хотя я не уверен на 100% в этом прямо сейчас.

Так что мой совет, как уже предлагали другие, состоит в том, чтобы максимально избегать using namespace, по крайней мере, в области видимости файла.Если вам нужно получить доступ ко многим вещам из одного пространства имен, просто поместите using namespace в функцию, которая в этом нуждается.Что касается пространства имен std, я настоятельно рекомендую никогда не использовать using namespace std.

0 голосов
/ 15 мая 2018

Ваше приложение функции перемещения было рассмотрено, и, к сожалению, было найдено лучшее приложение.Пожалуйста, не стесняйтесь обращаться к нам за комментариями или вопросами.

std :: move в служебном заголовке - это функция, вызываемая в этой ситуации.Это связано с несколькими факторами:

Когда вы снимите это условие, будет вызвана ваша функция.Например,

move((int)Direction::UP);

избавляет от необходимости неявного преобразования.

...