Насколько важно последовательное использование объявлений? - PullRequest
3 голосов
/ 27 сентября 2010

Большинство исследований, которые я провел по использованию объявлений, включая чтение соответствующих разделов различных руководств по стилю, указывают на то, стоит ли использовать объявления в исходных файлах C ++, если они появляются после всех #include , это решение оставлено на усмотрение кодера. Даже руководства по стилю, которые я читаю и которые обычно сводятся к одной или другой части таких распространенных споров ради последовательности, довольно гибки в этом отношении.

Мой вопрос, учитывая эту высокую степень гибкости, насколько важно использовать последовательный стиль? Например, предположим, что автор написал что-то вроде

using std::vector;

vector<T> v;

std::cout << v[0] << std::endl;

Является ли неприемлемым применение использования на std :: vector, но не на std :: cout или std :: endl в целом приемлемым, или это будет считаться недисциплинированным?

Ответы [ 5 ]

7 голосов
/ 27 сентября 2010

Я думаю, что весь смысл using в том, что вы используете его непоследовательно среди имен.Имена, которые вам нужны очень часто в одном блоке, могут быть объявлены локально с помощью объявления using, в то время как другие нет.Я не вижу проблемы с этим.

Объявлять имя для области имен всегда труднее.Я думаю, если известно, что имя принадлежит определенному пространству имен, так что не путать его с другими пространствами имен, не повредит объявлению использования, если оно делает ваш код более читабельным.

2 голосов
/ 27 сентября 2010

Теперь я решительный сторонник явного указания пространства имен (т. Е. Не «использования»)

История пространства имен большинства людей выглядит следующим образом (в нетривиальных проектах> 100kloc)

Невинность -> Стиль 1

using namespace std;

Ой -> стиль 2

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

ОК, хватит уже -> стиль 3

std::string foo = "xxx";
1 голос
/ 27 сентября 2010

Если вы нигде не говорите using namespace std;, я не думаю, что большинство разработчиков так или иначе заботятся о коде других людей.Единственное, что может их беспокоить - это чрезмерное использование std :: qualifier --- то есть если вы говорите «std :: vector» 20 раз в функции, возможно, пришло время для «using std :: vector»,В противном случае никого не должно волновать.

Иногда в своем собственном коде я специально использую квалификатор "std ::", чтобы указать, что это место only , в котором яиспользуя этот идентификатор.

0 голосов
/ 27 сентября 2010

Это не столько ответ, сколько контрапункт к нескольким другим ответам, которые всегда явно отстаивали включение пространства имен как части имени.Иногда это плохая идея.В некоторых случаях вы хотите использовать имя, которое было специализировано для данного типа , если оно существует , но в противном случае используйте стандартную альтернативу.

В качестве типичного примера давайте рассмотримфункция сортировки.Если вы сортируете некоторые объекты типа T, вы в конечном итоге поменяете их местами.Вы хотите использовать специальный swap(T &, T&), если он существует, но template <class T> std::swap в противном случае.

Если вы попытаетесь указать полное имя свопа, который вы собираетесь использовать явно, вы должны указать один илидругой - либо вы указываете специализированную версию, и создание экземпляра вашей сортировки по типу, который не определяет собственный своп, завершится неудачей, либо вы укажете std::swap и проигнорируете любой своп, предоставленный специально для типа, который вы 'Пересортировка.

using предоставляет выход из этой дилеммы, хотя:

using namespace std;

template <class T>
mysort(/* ... */ ) {

    // ...

    if (less(x[a], x[b])
        swap(x[a], x[b]);

    // ...
}

Теперь, если пространство имен, в котором найден T, содержит swap(T &, T&), оно будетнайдено с помощью зависимого от аргумента поиска и использовано выше.Если он не существует, то std::swap будет найден (и использован), потому что using namespace std; также сделал его видимым.

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

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

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

0 голосов
/ 27 сентября 2010

Я пытаюсь , а не , используя using (без каламбура).

Для сохранения набора текста мне нравится делать typedefs, например ::

typedef std::vector< int > IntVector;
typedef std::vector< Foo > FooVector;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...