Використання простору імен std


110

Здається, існують різні погляди на використання "використання" щодо простору імен std.

Одні кажуть, що використовують " using namespace std", інші кажуть, що не мають, а скоріше префіксу std-функцій, які слід використовувати " std::", а інші кажуть, що використовують щось подібне:

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;

для всіх функцій std, які потрібно використовувати.

Які плюси і мінуси у кожного?




Відповіді:


131

Більшість користувачів C ++ із задоволенням читають std::stringі std::vectorт. Д. Насправді, побачення сировини vectorзмушує мене замислитись, чи це визначено std::vectorіншим користувачем vector.

Я завжди проти використання using namespace std;. Він імпортує всілякі імена в глобальний простір імен і може викликати всілякі неочевидні двозначності.

Ось декілька загальних ідентифікаторів, які знаходяться в stdпросторі імен: підрахунок, сортування, пошук, рівний, зворотний. Локальна змінна, що називається, countозначає, що замість неї using namespace stdви не зможете використовувати .countstd::count

Класичний приклад небажаного конфлікту імен - це щось на зразок наступного. Уявіть, що ви новачок і не знаєте про це std::count. Уявіть, що ви або використовуєте щось інше, <algorithm>або його потягнуло, здавалося б, незв'язане заголовка.

#include <algorithm>
using namespace std;

int count = 0;

int increment()
{
    return ++count; // error, identifier count is ambiguous
}

Помилка, як правило, довга та недоброзичлива, оскільки std::countце шаблон із деякими довгими вкладеними типами.

Це все в порядку, оскільки він std::countпереходить у глобальний простір імен, а кількість функцій приховує його.

#include <algorithm>
using namespace std;

int increment()
{
    static int count = 0;
    return ++count;
}

Можливо, трохи дивно, це нормально. Ідентифікатори, імпортовані в декларативну область, з'являються у загальному просторі імен, який закриває і те, де вони визначені, і де вони імпортуються. Іншими словами, std::countвидно як countу глобальному просторі імен, але лише всередині increment.

#include <algorithm>

int increment()
{
    using namespace std;
    static int count = 0;
    return ++count;
}

І з подібних причин countтут неоднозначно. using namespace stdне викликає std::count, приховуйте зовнішнє, countяк можна було очікувати. У using namespaceправило означає , що std::countзовнішній вигляд (у incrementфункції) , як якщо б він був оголошений в глобальному масштабі, тобто в тому ж обсязі, int count = 0;і , отже , викликає неоднозначність.

#include <algorithm>

int count = 0;

int increment()
{
    using namespace std;
    return ++count; // error ambiguous
}

21
але вводити soooo набагато простіше без префікса std ::!
xtofl

69
@xtofl: Ні, це не так. П'ять символів не такі актуальні під час введення тексту, але ці п’ять символів можуть бути дуже доречними при читанні. А простота читання - це набагато більше, ніж простота введення вихідного коду, оскільки код набагато більше, ніж прочитаний.
sbi

3
Ви можете додати, що оператор use поводиться правильно з правилами застосування.
Мартін Йорк

2
@Martin York: Оновлено прикладами, що ілюструють правила розміщення. @Michael Burr: Це, мабуть, не так вже й погано, що мені насправді не подобається, коли повідомлення про помилки для простих помилок стають набагато складніше інтерпретувати, або там, де вони взагалі не трапляються. Наприклад, якщо функція вважається в області дії, але це не так, а функція std :: це, а не отримання корисної помилки "ідентифікатор не впізнаний", часто ви стикаєтеся з більш незрозумілою аргументом. Помилка стилю X 'або' не вдається генерувати функцію із шаблону ' Гірше, якщо неправильна функція викликається безшумно. Це рідко, але буває.
CB Bailey

5
Ну, я здивований, що ніхто не обговорював варіант using std::xxx;. Це не робить забруднення простору імен, код написання буде коротшим, і я думаю copy, що набагато більше читати, ніж std::copy.
legends2k

41

Виключення основ (Додавання std :: infront усіх stl-об'єктів / функцій і менший шанс конфлікту, якщо у вас немає "використання простору імен std")

Також варто зазначити, що ніколи не слід ставити

using namespace std

У файлі заголовка він може поширюватися на всі файли, що містять цей заголовок, навіть якщо вони не хочуть використовувати це простір імен.

У деяких випадках дуже корисно використовувати такі речі

using std::swap

Ніби є спеціалізована версія swap, компілятор буде використовувати це, інакше він знову впаде std::swap.

Якщо ви телефонуєте std::swap, ви завжди використовуєте основну версію, яка не буде викликати оптимізовану версію (якщо вона існує).


10
+1 для згадки using std::swap(що єдине, що я коли-небудь використовую).
sbi

1
+1 для згадки, яка u n sможе поширюватися. Зауважимо лише, що він також може проникнути в правильно побудовані заголовки: вони просто повинні бути включені після шахрайського заголовка.
quamrana

1
Але якщо ви визначаєте swapабо move(або hash, і lessт.д.) спеціалізації, ви повинні поставити цю спеціалізацію в namespace stdбудь-якому випадку. Наприклад:namespace std {template<> class hash<X> {public: size_t operator()(const X&) const};} class X: {friend size_t std::hash<X>::operator()(const X&)};
AJMansfield

28

По-перше, деяка термінологія:

  • використання-декларація : using std::vector;
  • використання-директива : using namespace std;

Я думаю, що використання use-директив добре, доки вони не використовуються в глобальній області застосування у заголовковому файлі. Так що маючи

using namespace std;

у вашому .cpp-файлі насправді не є проблемою, і якщо виявиться, він повністю під вашим контролем (і за бажанням його можна навіть охопити до окремих блоків). Я не бачу жодної конкретної причини захаращувати код за допомогою std::кваліфікації - це просто стає купою зорового шуму. Однак якщо ви не використовуєте stdв своєму коді цілу купу імен з простору імен, я також не бачу проблем із тим, щоб виключати директиву. Це тавтологія - якщо директива не потрібна, не потрібно її використовувати.

Аналогічно, якщо ви можете обійтись за допомогою декількох декларацій з використанням (замість використання директив ) для специфічних типів у stdпросторі імен, то немає жодної причини, щоб у вас не було лише тих специфічних імен, що вводяться у поточну область імен. З іншого боку, я вважаю, що було б божевільним і клопотом з бухгалтерського обліку мати 25 або 30 використання декларацій, коли одна директива використання також зробить трюк.

Також добре пам’ятати, що бувають випадки, коли потрібно використовувати декларацію з використанням. Перегляньте "Пункт 25 Скотта Майєра: Розгляньте підтримку заміни, що не кидається" з Ефективного C ++, Третя редакція. Для того, щоб загальна, шаблонна функція використовувала метод "кращого" swap для параметризованого типу, вам потрібно скористатися пошуком, який залежить від декларації та аргументу (як пошук ADL або Koenig):

template< typename T >
void foo( T& x, T& y)
{
    using std::swap;     // makes std::swap available in this function

    // do stuff...

    swap( x, y);         // will use a T-specific swap() if it exists,
                         //  otherwise will use std::swap<T>()

    // ...
 }

Я думаю, що ми повинні переглянути загальні ідіоми для різних мов, які суттєво використовують простори імен. Наприклад, Java і C # значною мірою використовують простори імен (можливо, більше, ніж C ++). Найбільш поширений спосіб використання імен в просторах імен на цих мовах - це їх масове приведення в поточний обсяг з еквівалентом директиви використання. Це не спричиняє проблем із широким розповсюдженням, і кілька разів з цією проблемою вирішуються за принципом "виняток", маючи справу з відповідними іменами за допомогою повнокваліфікованих імен або шляхом псевдоніму - як це можна зробити в C ++.

Герб Саттер та Андрій Олександреску про це говорять у "Пункт 59: Не записуйте вживання простору імен у файл заголовка або перед # включенням" своєї книги, Стандарти кодування C ++: 101 Правила, рекомендації та найкращі практики:

Коротше кажучи: Ви можете та маєте використовувати простір імен, використовуючи декларації та директиви вільно у своїх файлах реалізації після #includeдиректив, і почуватись добре з цим. Незважаючи на неодноразові твердження про протилежне, простір імен з використанням декларацій та директив не є злим, і вони не перешкоджають призначенню просторів імен. Швидше, саме вони роблять простори імен корисними.

Stroupstrup часто цитується: "Не забруднюйте глобальний простір імен" у "Мові програмування на C ++, третє видання". Насправді він говорить про це (C.14 [15]), але посилається на розділ C.10.1, де він говорить:

З допомогою декларування додає ім'я в локальній області видимості. З допомогою директиви робить; він просто надає імена, доступні в обсязі, в якому вони були оголошені. Наприклад:

namespaceX {
    int i , j , k ;
}

int k ;
void f1()
{
    int i = 0 ;

    using namespaceX ; // make names from X accessible

    i++; // local i
    j++; // X::j
    k++; // error: X::k or global k ?

    ::k ++; // the global k

    X::k ++; // X’s k
}

void f2()
{
    int i = 0 ;

    using X::i ; // error: i declared twice in f2()
    using X::j ;
    using X::k ; // hides global k

    i++;
    j++; // X::j
    k++; // X::k
}

Місцеве оголошене ім'я (оголошене або звичайною декларацією, або декларацією, що використовує) приховує нелокальні декларації з однойменною назвою, а будь-які незаконні перевантаження імені виявляються в точці декларації.

Зверніть увагу на помилку неоднозначності для k++в f1(). Глобальним іменам не надається перевага перед іменами з просторів імен, доступних у глобальному масштабі. Це забезпечує значний захист від випадкових зіткнень з іменами та, що важливо, - забезпечує відсутність переваг від забруднення глобального простору імен.

Коли бібліотеки, що декларують багато імен, стають доступними через використання директив, суттєвою перевагою є те, що сутички невикористаних імен не вважаються помилками.

...

Я сподіваюся побачити кардинальне зменшення використання глобальних імен у нових програмах із використанням просторів імен порівняно з традиційними програмами C та C ++. Правила для просторів імен були спеціально створені, щоб не надавати переваг "ледачому" користувачеві глобальних імен перед тим, хто дбає про те, щоб не забруднити глобальну сферу.

І як можна мати таку ж перевагу, як "ледачий користувач глобальних імен"? Скориставшись користувачем-директивою, яка безпечно робить імена в просторі імен доступними для поточної області.

Зауважте, що в stdпросторі імен є розмежування - імена, доступні для сфери застосування при належному використанні директиви використання (шляхом розміщення директиви після цього #includes), не забруднюють глобальний простір імен. Це просто зробити ці імена доступними легко та з постійним захистом від сутичок.


Що стосується вашої останньої точки: у Java та C # також є набагато акуратніші простори імен. Якби все в BCL жило в System, "використання системи" викликало б стільки ж проблем, як і "використання простору імен std".
Джефф Харді

Але програми Java та C #, які я бачу, зазвичай містять у всіх просторах імен, які вони використовують - не лише "Система" (або її еквівалент). Тож замість єдиної директиви, що використовує всі імена, що використовуються, є 5 або 10, які роблять більш-менш те саме. Також "використовує простір імен std;" справді викликає стільки неприємностей?
Майкл Берр

Проблема полягає в тому, що std має занадто багато загальних імен і що, включаючи один стандартний заголовок, може включати всі інші. Ми не маємо належного контролю над тим, що імпортується, занадто багато ризиків. Я не знаю достатньо про Java та C #, але я знаю про Ада, яка має набагато кращу модульну систему, ніж C ++ і де зазвичай іммуються імпортування імен. Взагалі, його перше питання полягає у назві конвенції (я бачив людей, що використовують префікс, а також простір імен, не імпортуючи, не має сенсу), а потім про стиль.
AProgrammer

1
Я досі не переконаний, що це проблема в реальному світі. Я бачу використання директив, що використовуються весь час без серйозних недоліків. Знову ж таки, у мене немає проблем з тим, щоб не використовувати їх. Я просто вважаю за краще, щоб std::кваліфікуючі не захаращували код - є й інші способи цього уникнути (за допомогою декларацій або typedefs зазвичай виконують трюк).
Майкл Берр

1
@AProgrammer: ви говорите: "список - це природний ідентифікатор для ідентифікації списку в інтерпретаторі lisp", але наявність " using namespace std;" директиви не заважає вам оголосити свій природний ідентифікатор list"- це просто так, якщо ви це зробите, ви не можете довше використання std::listбез кваліфікації. Це не інакше, ніж якщо немає " using namespace std;" директиви. Або я щось пропускаю?
Майкл Берр

17

Ніколи не використовуйте простір імен у глобальному масштабі у файлі заголовка. Це може призвести до конфлікту, і особа, яка відповідає за файл, де конфлікт виявляється, не контролює причину.

У файлі реалізації вибір набагато менш чіткий.

  • Якщо розмістити std з використанням простору імен, всі символи з цих просторів імен. Це може бути клопітно, оскільки майже жоден орган не знає всіх символів, які там є (тому політику конфлікту неможливо застосувати на практиці), не кажучи про символи, які будуть додані. А стандарт C ++ дозволяє заголовку додавати символи з інших заголовків (C - це не дозволяє). Це все ще може добре працювати на практиці для спрощення написання у контрольованому випадку. І якщо виникла помилка, вона виявляється у файлі, який має проблему.

  • Введення за допомогою std :: name; має перевагу у простоті написання без ризику імпортування невідомих символів. Вартість полягає в тому, що вам потрібно імпортувати явно всі потрібні символи.

  • Явно кваліфікуючі додають трохи затруднень, але я думаю, що це менше проблем у деяких практиках.

У своєму проекті я використовую явну кваліфікацію для всіх імен, я приймаю використання std :: name, я борюся з використанням простору імен std (у нас є інтерпретатор lisp, який має свій тип списку, і тому конфлікт - це впевнене).

Для інших просторів імен ви також повинні враховувати використовувані умови імен. Мені відомо про проект, який використовує простір імен (для версії версій) та префікс імен. Робити using namespace Xтоді майже не ризикуєш, а не робити цього призводить до дурного вигляду коду PrefixNS::pfxMyFunction(...).

Є деякі випадки, коли потрібно імпортувати символи. std :: swap - найпоширеніший випадок: ви імпортуєте std :: swap, а потім використовуєте swap некваліфікований. Пошук, залежний від аргументів, знайде адекватний своп у просторі імен типу, якщо він є, і повернеться до стандартного шаблону, якщо його немає.


Редагувати:

У коментарях Майкл Берр цікавиться, чи виникають конфлікти в реальному світі. Ось справжній живий приклад. У нас мова розширення з - це нарічний діалект. У нашого перекладача є файл, що включає в себе файл lisp.h

typedef struct list {} list;

Нам довелося інтегрувати та адаптувати деякий код (який я назву "двигун"), який виглядав так:

#include <list>
...
using std::list;
...
void foo(list const&) {}

Тому ми модифікували так:

#include <list>

#include "module.h"
...
using std::list;
...
void foo(list const&) {}

Добре. Все працює. Через кілька місяців "module.h" було змінено на "list.h". Тести пройшли. "модуль" не був змінений таким чином, що впливав на його ABI, тому бібліотеку "двигуна" можна було використовувати без повторної компіляції користувачів. Інтеграційні тести були в порядку. Опубліковано новий "модуль". Наступна компіляція двигуна була порушена, коли його код не був змінений.


1
Один з контрольованих випадків, коли я вважаю прийнятним використання простору імен, - це публікація коду. Спрощення полегшує компонування сторінки та допомагає зосередитись на відкритій точці. Недолік полягає в тому, що він насправді не показує належної практики, тому я б не використовував його в книгах для початківців.
AProgrammer

1
Я думаю, що набравши std :: це невелика ціна, щоб заплатити за чіткість
paoloricardo

4
@paoloricardo: З іншого боку, я думаю, що std :: з'являтися всюди - це непотрібне зорове скупчення.
Майкл Берр

1
@Michael: ти платиш гроші і робиш свій вибір!
paoloricardo

2
Дякуємо, що знайшли час, щоб додати деталі проблеми, з якою ви зіткнулися.
Майкл Берр

4

Якщо у вас немає ризику конфлікту імен у коді з std та іншими бібліотеками, ви можете використовувати:

using namespace std;

Але якщо ви хочете точно знати залежність вашого коду від документації або є ризик конфлікту імен, використовуйте інший спосіб:

using std::string;
using std::cout;

Третє рішення, не використовуйте ці рішення і не пишіть std :: перед кожним використанням у коді приносить вам більше безпеки, але, можливо, трохи важкості в коді ...


4

І те й інше

using std::string;

і

using namespace std;

додати деякі символи (один чи багато) до глобального простору імен. І додавання символів до глобального простору імен - це те, що ніколи не слід робити у файлах заголовків. Ви не маєте контролю над тим, хто буде включати ваш заголовок, є багато заголовків, які включають інші заголовки (і заголовки, які включають заголовки, які включають заголовки тощо).

У реалізації (.cpp) файлів вам належить (пам'ятайте це робити лише після всіх директив #include). Ви можете зламати лише код у цьому конкретному файлі, тому простіше керувати та з’ясовувати причину конфлікту імен. Якщо ви віддаєте перевагу використовувати std :: (або будь-який інший префікс, у вашому проекті може бути багато просторів імен) перед відмітниками, це нормально. Якщо ви хочете додати ідентифікатори, які ви використовуєте, у глобальний простір імен, це нормально. Якщо ви хочете принести на голову цілий простір імен :-), це залежить від вас. Хоча ефекти обмежуються однією компіляційною одиницею, це прийнятно.


3

Для мене я вважаю за краще використовувати, ::коли це можливо.

std::list<int> iList;

Я ненавиджу писати:

for(std::list<int>::iterator i = iList.begin(); i != iList.end(); i++)
{
    //
}

Сподіваюся, з C ++ 0x я би написав це:

for(auto i = iList.begin(); i != iList.end(); i++)
{
    //
}

Якщо простір імен дуже тривалий,

namespace dir = boost::filesystem;

dir::directory_iterator file("e:/boost");
dir::directory_iterator end;

for( ; file != end; file++)
{
    if(dir::is_directory(*file))
        std::cout << *file << std::endl;
}

@AraK: простір імен dir = boost :: файлова система; Я думаю, це псевдонім?
paoloricardo

@paoloricardo: Так, це те, що це.
sbi

2
Ітератори слід нарощувати ++iне i++тому, що, якщо це навіть визначено, створюється непотрібна тимчасова копія ітератора.
Фелікс Домбек

2

Ви ніколи не повинні знаходитись using namespace stdу просторі імен у заголовку. Крім того, я вважаю, що більшість програмістів будуть дивуватися, коли вони бачать vectorчи stringбез std::, тому я думаю, що це не using namespace stdкраще. Для цього я стверджую, що взагалі ніколи не буде using namespace std.

Якщо вам здається, що потрібно, додайте місцеві, використовуючи декларації, як using std::vector. Але запитайте себе: чого це варто? Рядок коду пишеться один раз (можливо, двічі), але він читається десять, сто чи тисячі разів. Заощаджене зусилля набору тексту для додавання використовуючої декларації чи директиви є незначним порівняно із зусиллями для читання коду.

Зважаючи на це, в проекті десять років тому ми вирішили чітко класифікувати всі ідентифікатори з їхніми повними просторами імен. Те, що здавалося незручним спочатку, стало звичним протягом двох тижнів. Зараз у всіх проектах цілої компанії вже ніхто не використовує директив чи декларацій. (За одним винятком, див. Нижче). Переглядаючи код (кілька MLoC) через десять років, я відчуваю, що ми прийняли правильне рішення.

Я виявив, що зазвичай ті, хто виступає проти заборони, usingзазвичай не пробували цього проекту. Ті, хто намагався, часто вважають це краще, ніж використовувати директиви / декларації через дуже короткий час.

Примітка. Єдине виняток - це те, using std::swapщо необхідно (особливо в загальному коді), щоб отримати перевантаження, swap()які не можна помістити в stdпростір імен (тому що нам не дозволяється ставити перевантаження stdфункцій у цей простір імен).


3
Спеціалізація std :: swap була б повною спеціалізацією - ви не можете частково спеціалізувати шаблони функцій. Будь-яка програма буде дозволено частково спеціалізувати будь-який стандартний шаблон бібліотеки, поки що спеціалізація залежить від обумовленого користувачем типу.
CB Bailey

@Charles: Так, ти маєш рацію, звичайно, немає FTPS. І я можу спеціалізувати шаблони всередині std, але не перевантажувати. Вибачте за цю мозкову дальність. Я виправлю посаду.
sbi

2
Я не думаю, що метою using namespaceдирективи було також вводити текст ; скоріше, це було полегшити читання , оскільки, як ви кажете, цей код доведеться читати десятки, сотні чи тисячі разів. А для деяких людей це читається набагато легше, з меншим std::безладом. Але це, ймовірно, зводиться до особистої сприйнятливої ​​здатності; деякі люди відфільтровують std::або навіть потребують цього для настанови (як серіфи), інші натикаються на нього і відчувають себе, як на кучерявій дорозі.
Лумі


1
@sbi: Ні, це не об'єктивно. Це залежить від того, чи ви вважаєте, що std :: є корисним чи неспокійним. Більше захаращення -> менша чіткість.
Джошуа Річардсон

2

У просторах імен зберігається код, що міститься для запобігання плутанини та забруднення підписів функції.

Ось повна та задокументована демонстрація правильного використання простору імен :

#include <iostream>
#include <cmath>  // Uses ::log, which would be the log() here if it were not in a namespace, see /programming/11892976/why-is-my-log-in-the-std-namespace

// Silently overrides std::log
//double log(double d) { return 420; }

namespace uniquename {
    using namespace std;  // So we don't have to waste space on std:: when not needed.

    double log(double d) {
        return 42;
    }

    int main() {
        cout << "Our log: " << log(4.2) << endl;
        cout << "Standard log: " << std::log(4.2);
        return 0;
    }
}

// Global wrapper for our contained code.
int main() {
    return uniquename::main();
}

Вихід:

Our log: 42
Standard log: 1.43508

1

using namespace stdімпортує вміст stdпростору імен у поточному. Таким чином, перевага полягає в тому, що вам не доведеться вводити std::всі функції цього простору імен. Однак може статися, що у вас є різні простори імен, які мають функції одного і того ж імені. Таким чином, ви можете закінчити не дзвонити тому, кого ви хочете.

Визначення вручну, в які ви хочете імпортувати, stdзапобігає тому, що може статися, але це може призвести до довгого списку використання на початку вашого файлу, який деякий розробник вважатиме некрасивим;)!

Особисто я вважаю за краще вказувати простір імен кожного разу, коли я використовую функцію, за винятком випадків, коли простір імен занадто довгий, і в такому випадку я ставлю деякі з них на початку файлу.

EDIT: як зазначено в іншій відповіді, ніколи не слід ставити файл using namespaceу заголовку, оскільки він передаватиметься всім файлам, включаючи цей заголовок, і таким чином може спричинити небажану поведінку.

EDIT2: виправив мою відповідь, завдяки коментарю Чарльза.


2
using namespace std;імпортує вміст stdпростору імен у глобальний простір імен. Це не змінює простір імен за замовчуванням. Визначення чогось у глобальному просторі імен після using namespace stdзнака магічного не покладе його у область stdімен.
CB Bailey

Вибачте, це я не мав на увазі. Дякую, що вказав на це, я виправлю свою відповідь.
Wookai

1
Хлопці: дякую за відповіді. Здається, що, як правило, безпечніше не використовувати "використання простору імен std" і уникати створення потенційних двозначностей. На балансі, використовуючи 'std :: xxx', звертається до мене більше, ніж оголошувати перелік різних функцій на початку вихідного файлу, оскільки він однозначно визначає, у чому полягає його наміри.
paoloricardo

1
Цитата (за винятком випадків, коли простір імен занадто довгий). Ви можете використати псевдонім простору імен, щоб допомогти там. 'простір імен Rv1 = Thor :: XML :: XPath :: Правила :: Light :: Version1;' Зверніть увагу на псевдоніми та використовуючи обидва правила добору правил;
Мартін Йорк

0

Так само, як у Java, де ви можете використовувати або можна включити java.util. * Або просто вибрати кожен клас окремо, це залежить від стилю. Зауважте, що ви не хочете його using namespace stdна початку файлу / широкого діапазону, тому що ви забруднити простір імен і, можливо, матимуть сутички, переможивши точку просторів імен. Але якщо у вас є функція, яка використовує багато STL, вона захаращує код, маючи у вашій логіці кучу синтаксису префіксів, і вам, мабуть, варто розглянути можливість використання using namespace std(при використанні різних класів) або окремих usings (при використанні декількох заняття часто).


0

Ця дискусія буде активною до тих пір, поки IDE, з яким ви працюєте, не є досить гнучким, щоб показати або приховати точну інформацію, яка вам потрібна.

Це тому, що ви хочете, щоб ваш код виглядав, залежить від завдання.

Створюючи свій вихідний код, я вважаю за краще точно бачити, який клас я використовую: це std::stringчи BuzFlox::Obs::stringклас?

Під час проектування потоку управління мене навіть не цікавлять типи змінних, але я хочу зосередитись на if's і while' s і continue's.

Отже, це моя порада:

Залежно від аудиторії вашого коду та потужності ваших інструментів, вибирайте спосіб, який читається найпростіше, або дає найбільшу інформацію.


0

Існує кілька способів виправити це.

По-перше: використовуйте як те, що ви робили.

Друге: зробіть namespace S = std;, скорочуючи 2 знаки.

Третє: використання static.

Четверте: не використовуйте імена, які stdвикористовує.


-1

Які плюси і мінуси кожного

Єдина причина, щоб відмовитися від std :: - це те, що теоретично ви могли самостійно повторно виконувати всі функції STL. Тоді ваші функції можна буде переключити з використання std :: vector на мій :: вектор без зміни коду.


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

Так, єдине виправдання директиви "using", яка порушує це, - це можливість перемикати функції на новий простір імен.
Мартін Бекетт

Я думаю, ви знайдете дуже багато програмістів, які скаржаться на те, що болить у просторах імен попу, і хочуть викинути їх у вікно, якщо б не було директиви щодо використання. Наскільки я знаю, кожна мова, яка використовує простори імен, має щось подібне до використання-директиви, щоб вивести їх із шляху, коли ви хочете їх вийти з шляху. Якщо директиви марні, чому вони існують всюди?
Майкл Берр

Я думаю, що "використання" покликане було перейти до альтернативних реалізацій, а не для введення 3-х літер. Мені подобається використовувати "std :: Foo", оскільки він служить договором програмісту, що я використовую звичайний Foo, і вони не повинні перевіряти. Я згоден, я не хотів би вводити "com.microsoft.visual-studio.standard-library.numbers.int foo", деякі декларації ітератора в STL стають подібними. Python виконує гарну роботу, дозволяючи вам витягувати з модулів декоровані або неокрашені набори функцій.
Мартін Бекетт

-1

Чому б не, наприклад

typedef std::vector<int> ints_t;
ints_t ints1;
....
ints_t ints2;

замість незворушного

std::vector<int> ints1;
...
std::vector<int> ints2;

Я вважаю, що це набагато читає і мій стандарт кодування.

Ви навіть можете використовувати його для включення деякої смислової інформації для читача. Наприклад, розглянемо прототипи функцій

void getHistorgram(std::vector<unsigned int>&, std::vector<unsigned int>&);

які повертають значення?

Як натомість

typedef std::vector<unsigned int> values_t;
typedef std::vector<unsigned int> histogram_t;
...
void getHistogram(values_t&, histogram_t&); 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.