Я использую объявление using в C++, чтобы добавить std :: string и std :: vector в локальное пространство имен (чтобы не вводить ненужные символы std ::).
using std::string;
using std::vector;
class Foo { /*...*/ };
Каков объем этого объявления? Если я сделаю это в заголовке, будет ли он вставлять эти объявления using в каждый файл cpp, который включает заголовок?
Фактически, не помещайте объявление using (тем более директива) в заголовок совсем, даже в пространстве имен! См. объем использования объявления в пространстве имен для проблем, которые это вызывает.
@NilsvonBarth: Это немного упрощено. Использование using в области классов и функций безопасно в отношении обсуждаемой проблемы.
Возможно, вам будет интересно прочитать о Поиск ADL C++характерная черта.





В указанном случае - файл («единица перевода»), что означает «да», каждый файл, который ее включает.
Вы также можете поместить оператор using внутри класса, и в этом случае он действует только для этого класса.
Как правило, если вам нужно указать пространство имен в заголовке, часто лучше просто полностью указать каждый необходимый идентификатор.
Обратите внимание, что объявление using в классе не ведет себя так же, как вне класса - например, вы не можете использовать его, чтобы ввести cout вместо std::cout в область действия класса.
Это верно. Область видимости - это модуль, который использует объявление using. Если какие-либо файлы заголовков, которые включает модуль, имеют объявления using, областью этих объявлений будет этот модуль, а также любые другие модули, которые включают те же заголовки.
Когда вы #include заголовочный файл в C++, он помещает все содержимое заголовочного файла в то место, которое вы включили в исходный файл. Таким образом, включение файла с объявлением using имеет тот же эффект, что и объявление using в верхней части каждого файла, который включает этот файл заголовка.
... что вообще плохо.
Но если вы поместите объявление using внутри namespace, оно будет ограничено рамками этого пространства имен, так что в целом это нормально (с обычными оговорками в отношении ваших конкретных потребностей и стиля).
... но если вы помещаете using в пространство имен, убедитесь, что вы не пытаетесь обойти что-то, что обычно является плохой идеей, например, вы не можете заключить методы класса, объявленные вне пространства имен Y, внутри другого пространство имен X, чтобы вы могли локально использовать пространство имен X. Вот почему мы в первую очередь использовали namespace :: resolvers. Если это такая большая проблема с набором текста, либо макрос (который может легко привести к запаху кода), либо, что еще лучше, изолировать его в собственном исходном файле .cpp, где вы будете использовать пространство имен только там.
Хотя этот и подобные ответы являются хорошими советами, они не отвечают на вопрос.
В файлах заголовков нет ничего особенного, что могло бы не допустить объявления using. Это простая замена текста еще до начала компиляции.
Вы можете ограничить объявление using областью действия:
void myFunction()
{
using namespace std; // only applies to the function's scope
vector<int> myVector;
}
Никогда не думал, что смогу использовать его внутри функции!
У меня есть куча пространств имен, которые все используются одним файлом типа «конгломератор», и модульное тестирование gmock было очень утомительным, потому что каждый тест использовал вещи из определенного пространства имен, и я думал, что должен квалифицировать каждую переменную. Использование using внутри функции (или даже макроса gtest TEST!) Делает мою жизнь намного лучше!
Область видимости - это та область, в которой находится объявление using.
Если это глобальная область видимости, то она будет глобальной. Если он находится в глобальной области действия файла заголовка, то он будет в глобальной области видимости каждого исходного файла, который включает заголовок.
Итак, общий совет - избегать использования объявлений в глобальной области заголовочных файлов.
Этого недостаточно. Заменить Избегать на Не
Но избегать лучше, чем не делать. «Избегайте попадания в другие машины»
Объем оператора using зависит от того, где он находится в коде:
Я думал, что невозможно добавить оператор using в область действия класса ...? Из-за этого у меня был тот же вопрос, что и у OP, так как я не хотел постоянно набирать std::. У меня есть классы, которые используют много векторов с умными указателями, а пятисимвольный префикс std:: добавляет большую длину строки, что, как мне кажется, читается хуже. Поэтому мне было интересно, в порядке ли директива using в пространстве имен, содержащем класс? (Даже если в заголовке.)
Что насчет того, если он помещен в сферу namespace { ... }?
Таким образом, вы можете полностью написать: {using namespace blabla; class blah {}; } и что использование будет применяться только к классу?
Есть несколько безоговорочных комментариев, когда они говорят «Не делайте этого». Это слишком сурово, но нужно понимать, когда это нормально.
Запись using std::string - это никогда не нормально. Запись using ImplementationDetail::Foo в ваш собственный заголовок, когда этот заголовок объявляет ImplementationDetail :: Foo, может быть в порядке, тем более, если объявление using происходит в вашем пространстве имен. Например.
namespace MyNS {
namespace ImplementationDetail {
int Foo;
}
using ImplementationDetail::Foo;
}
Затем пользователь заголовка может записать MyNS::Foo
Лучшим примером является using boost::posix_time::ptime. Конечно, пользователь мог бы написать MyNS::ptime, но это еще не конец света, и это может быть компенсировано удобством наличия таких функций, как MyFunction(ptime a, ptime b).
using std::string никогда не годится? Даже в вашем собственном пространстве имен, чтобы сохранить много префиксов std::?
@thomthom - это нормально, если он заключен в область видимости, такую как ваше собственное пространство имен.
На всякий случай это не ясно из других ответов здесь: - Не помещайте объявление
using(или директивуusing) в область видимости файла во включаемом файле / заголовке! Это вызовет головную боль для пользователей заголовка.