Могу ли я отменить эффект «использования пространства имен» в C ++? - PullRequest
31 голосов
/ 28 января 2010

С помощью using namespace я делаю все содержимое этого пространства имен видимым без использования квалификатора пространства имен. Это может вызвать проблемы, если using namespace встречается в широко используемых заголовках - мы можем непреднамеренно сделать два пространства имен с одинаковыми именами классов видимыми, и компилятор откажется компилировать, если к имени класса не добавляется префикс квалификатора пространства имен.

Можно ли отменить using namespace, чтобы компилятор забыл, что видел его раньше?

Ответы [ 5 ]

35 голосов
/ 28 января 2010

Нет, но вы можете сказать своим коллегам, что у вас никогда не должно быть директивы или объявления using в заголовке.

15 голосов
/ 28 января 2010

Как говорили другие, вы не можете, и проблема не должна быть на первом месте.
Следующая лучшая вещь, которую вы можете сделать, это ввести нужные символы, чтобы их предпочитал поиск по имени:

namespace A { class C {}; }
namespace B { class C {}; }
using namespace A;
using namespace B;

namespace D {
    using A::C; // fixes ambiguity
    C c;
}

В некоторых случаях вы также можете обернуть оскорбительные включения в пространство имен:

namespace offender {
#  include "offender.h"
}
6 голосов
/ 28 января 2010

Нет, C ++ Standard ничего не говорит о "отмене". Лучшее, что вы можете сделать, это ограничить область действия using:

#include <vector>

namespace Ximpl {

using namespace std;    
vector<int> x;

}

vector<int> z; // error. should be std::vector<int>

Но, к сожалению, using namespace Ximpl также принесет все имена из std пространства имен.

3 голосов
/ 28 января 2010

Насколько мне известно ... Но, как правило, я использую только "использование пространства имен" в файлах .cpp.

0 голосов
/ 13 декабря 2013

Самое близкое, что я попытаюсь использовать в заголовочных файлах, это:

//example.h

#ifndef EXAMPLE_H_
#define EXAMPLE_H_


/**
 * hating c++ for not having "undo" of using namespace xx
 */
#define string std::string
#define map std::map

class Example {
public:
    Example (const char *filename);
    Example (string filename);
    ~Example ();
private:
    map<string,complicated_stuff*> my_complicated_map;

};

#undef string
#undef map

#endif //EXAMPLE_H_

В конце концов, определения #undef -able. Есть 2 проблемы: 1. это некрасиво 2. используются отдельные #define и #undef для каждого имени из соответствующего пространства имен

...