Какова область применения "использования" в С++?

Я использую декларацию 'using' в С++ для добавления std::string и std::vector в локальное пространство имен (чтобы сохранить ввод ненужных "std::" ).

using std::string;
using std::vector;

class Foo { /*...*/ };

Какова область применения этой декларации? Если я сделаю это в заголовке, будет ли он вводить эти "использование" объявлений в каждый файл cpp, который включает заголовок?

Ответ 1

Когда вы # включаете заголовочный файл в С++, он помещает все содержимое файла заголовка в то место, которое вы включили в исходный файл. Таким образом, включая файл с объявлением using имеет точный эффект размещения объявления using в верхней части каждого файла, который включает этот файл заголовка.

Ответ 2

Нет ничего особенного в файлах заголовков, которые сохраняли бы объявление using. Это простая подстановка текста до начала компиляции.

Вы можете ограничить объявление using областью действия:

void myFunction()
{
   using namespace std; // only applies to the function scope
   vector<int> myVector;
}

Ответ 3

Объем оператора using зависит от того, где он находится в коде:

  • Размещенный в верхней части файла, он имеет область видимости в этом файле.
  • Если это файл заголовка, он будет иметь область видимости во всех файлах, которые содержат этот заголовок. В общем, это "не очень хорошая идея", поскольку это может иметь неожиданные побочные эффекты.
  • В противном случае оператор using имеет область видимости внутри блока, которая содержит его от точки, в которой она встречается до конца блока. Если он помещен внутри метода, он будет иметь область действия внутри этого метода. Если он помещен в определение класса, он будет иметь область видимости внутри этого класса.

Ответ 4

В приведенном случае файл ( "единица перевода" ), что означает "да", каждый файл, который включает его.

Вы также можете поместить оператор using внутри класса, и в этом случае он действует только для этого класса.

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

Ответ 5

Область - это область видимости, в которой используется декларация использования.

Если это глобальная область, то она будет находиться в глобальном масштабе. Если он находится в глобальной области заголовка, то он будет находиться в глобальной области каждого исходного файла, который включает заголовок.

Итак, общий совет: избегать использования объявлений в глобальной области заголовков.

Ответ 6

Это правильно. Область - это модуль, который использует объявление using. Если в каких-либо файлах заголовков, содержащихся в модуле, есть объявления using, область этих деклараций будет являться этим модулем, а также любыми другими модулями, которые содержат одни и те же заголовки.

Ответ 7

Есть несколько комментариев, которые являются довольно неквалифицированными, когда они говорят "Не делать". Это слишком строго, но вы должны понять, когда все в порядке.

Запись using std::string никогда не будет ОК. Написание using ImplementationDetail::Foo в вашем собственном заголовке, когда этот заголовок объявит, что реализацияDetail:: Foo может быть ОК, moreso, если объявление использования происходит в вашем пространстве имен. Например.

namespace MyNS {
    namespace ImplementationDetail {
        int Foo;
    }
    using ImplementationDetail::Foo;
}