Neden "std ad alanı kullanılıyor?" kötü bir uygulama olarak kabul edildi mi?

Sep 21 2009

Yazmaktan o başkaları tarafından söylendi using namespace std;kodunda yanlış olduğunu ve kullanması gerektiğini std::coutve std::cinyerine doğrudan.

Neden using namespace std;kötü bir uygulama olarak kabul edilir? Verimsiz mi yoksa belirsiz değişkenler ( stdad alanındaki bir işlevle aynı adı paylaşan değişkenler) bildirme riski var mı? Performansı etkiler mi?

Yanıtlar

2351 GregHewgill Sep 21 2009 at 10:13

Bunun performansla hiçbir ilgisi yoktur. Ama şunu bir düşünün: Foo ve Bar adında iki kitaplık kullanıyorsunuz:

using namespace foo;
using namespace bar;

Her şey yolunda Blah()gidiyor ve Foo'dan ve Quux()Bar'dan sorunsuz bir şekilde arayabilirsiniz . Ancak bir gün, şimdi adlı bir işlevi sunan Foo 2.0'ın yeni bir sürümüne yükseltiyorsunuz Quux(). Artık bir çatışmanız var: Hem Foo 2.0 hem de Bar Quux()global ad alanınıza aktarılır. Bu, özellikle işlev parametreleri eşleşirse, düzeltmek için biraz çaba sarf edecektir.

Eğer kullanılmış olsaydı foo::Blah()ve bar::Quux()ardından giriş foo::Quux()olmayan bir olay olurdu.

1442 sbi Sep 21 2009 at 16:26

Greg'in yazdığı her şeye katılıyorum ama eklemek istiyorum: Greg'in söylediğinden bile daha kötüsü olabilir!

Kütüphane Foo 2.0 bir işlev tanıtmak olabilir Quux()için aramaların bazıları için bir açık bir şekilde daha iyi bir maç olduğunu, Quux()daha bar::Quux()yıllarca adı verilen kod. Sonra kodunuz hala derlenir , ancak sessizce yanlış işlevi çağırır ve tanrı bilir ne yapar. İşlerin alabileceği en kötü şey bu.

Unutmayın stdad bunların çoğu tanımlayıcıları, tonlarca vardır çok yaygın olanları (düşünmek list, sort, string, iteratorçok başka bir kod görünmesini çok muhtemeldir, vs.).

Bunun olası olmadığını düşünürseniz: Burada Stack Overflow'da sorulan bir soru vardı, hemen hemen tam olarak bunun olduğu yerde (atlanmış std::önek nedeniyle yanlış işlev çağrıldı ) bu yanıtı verdikten yaklaşık yarım yıl sonra. İşte böyle bir sorunun daha yeni bir örneği. Yani bu gerçek bir problem.


Burada bir veri noktası daha var: Uzun yıllar önce, standart kitaplıktan her şeyin önüne eklenmesi gerektiğini de can sıkıcı buluyordum std::. Daha sonra usingfonksiyon kapsamları dışında hem yönergelerin hem de bildirimlerin yasaklandığına karar verildiği bir projede çalıştım . Bil bakalım ne oldu? Öneki yazmaya alışmamız çoğumuzun birkaç haftasını aldı ve birkaç hafta sonra çoğumuz bunun kodu daha okunabilir hale getirdiğini bile kabul etti . Bunun bir nedeni var: Daha kısa veya daha uzun düzyazı sevip sevmemek özneldir, ancak önekler koda nesnel olarak netlik katar. Yalnızca derleyici değil, siz de hangi tanımlayıcıya başvurulduğunu görmeyi daha kolay bulacaksınız.

On yılda, bu proje birkaç milyon satır koda sahip olacak şekilde büyüdü. Bu tartışmalar tekrar tekrar gündeme geldiğinden, bir zamanlar usingprojede (izin verilen) işlev kapsamının gerçekte ne sıklıkla kullanıldığını merak etmiştim . Bunun için kaynakları büyüttüm ve kullanıldığı yerde sadece bir veya iki düzine yer buldum. Bana göre bu, geliştiricilerin, std::kullanılmasına izin verildiği durumlarda bile, her 100 kLoC'de bir kez bile yönergeleri kullanmak için yeterince acı verici bulmadıklarını gösteriyor.


Sonuç olarak: Her şeyin açıkça önüne eklenmesi herhangi bir zarar vermez, alışmak çok az zaman alır ve nesnel avantajları vardır. Özellikle, kodun derleyici ve insan okuyucular tarafından yorumlanmasını kolaylaştırır ve muhtemelen kod yazarken asıl amaç bu olmalıdır.

453 ChrisW Sep 21 2009 at 10:22

using namespaceSınıflarınızın başlık dosyalarını yerleştirmenin sorunu , sınıflarınızı kullanmak isteyen herkesi (başlık dosyalarınızı dahil ederek) diğer ad alanlarını da 'kullanmaya' (yani her şeyi görmeye) zorlamasıdır.

Ancak, (özel) * .cpp dosyalarınıza using ifadesi koymakta özgürsünüz.


Bazı kişilerin bu şekilde "özgür hisset" dediğime katılmadığına dikkat edin - çünkü usingcpp dosyasındaki bir ifade başlıktan daha iyi olsa da (çünkü başlık dosyanızı içeren insanları etkilemez), hala olmadığını düşünüyorlar iyi (çünkü koda bağlı olarak sınıfın uygulanmasını sürdürmeyi daha zor hale getirebilir). Bu C ++ Süper SSS girişi şöyle diyor:

Using-yönergesi eski C ++ kodu için ve ad alanlarına geçişi kolaylaştırmak için vardır, ancak muhtemelen bunu düzenli olarak kullanmamalısınız, en azından yeni C ++ kodunuzda kullanmamalısınız.

SSS iki alternatif önerir:

  • Bir kullanım beyanı:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • Sadece std yazarak ::

    std::cout << "Values:";
    
241 DavidThornley Oct 29 2010 at 00:37

Geçenlerde Visual Studio 2010 ile ilgili bir şikayet ile karşılaştım . Hemen hemen tüm kaynak dosyalarının şu iki satıra sahip olduğu ortaya çıktı:

using namespace std;
using namespace boost;

Pek çok Boost özelliği C ++ 0x standardına giriyor ve Visual Studio 2010'da birçok C ++ 0x özelliği var, bu yüzden aniden bu programlar derlenmiyordu.

Bu nedenle, kaçınmak using namespace X;, geleceğe yönelik bir koruma biçimidir, kullanımdaki kitaplıklarda ve / veya başlık dosyalarında yapılacak bir değişikliğin bir programı bozmayacağından emin olmanın bir yoludur.

216 mattnewport Nov 04 2014 at 03:00

Kısa versiyon: usingbaşlık dosyalarında genel bildirimler veya yönergeler kullanmayın . Bunları uygulama dosyalarında kullanmaktan çekinmeyin. İşte ne Herb Sutter ve Andrei Alexandrescu bu konuda söylemek zorunda Standartları Kodlama C ++ (vurgu için kalınlaştırmak benimdir):

Özet

Ad alanı kullanımları size kolaylık sağlamak içindir, başkalarına zorlamanız için değildir: Bir #include yönergesinden önce asla bir using bildirimi veya using yönergesi yazmayın.

Sonuç: Başlık dosyalarında, yönergeleri veya bildirimleri kullanarak ad alanı düzeyinde yazmayın; bunun yerine, tüm adları açıkça ad alanını nitelendirin. (İkinci kural birinciden sonra gelir çünkü başlıklar, onlardan sonra başka hangi başlıkların #includes görünebileceğini asla bilemez.)

Tartışma

Kısaca: #include yönergelerinden sonra uygulama dosyalarınızda bildirimleri ve yönergeleri özgürce kullanarak ad alanını kullanabilir ve kullanmalısınız ve bu konuda kendinizi iyi hissetmelisiniz. Aksine tekrarlanan iddialara rağmen, bildirimler ve yönergeler kullanan ad alanı kötü değildir ve ad alanlarının amacını bozmazlar. Aksine, ad alanlarını kullanılabilir kılan şey onlardır .

128 robson3.14 Sep 21 2009 at 22:47

Bir kullanmamalısınız usingözellikle başlıklarında, küresel kapsamda yönergeyi. Bununla birlikte, bir başlık dosyasında bile uygun olduğu durumlar vardır:

template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
    using namespace std; // No problem since scope is limited
    return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}

Bu, açık nitelendirmeden ( std::sin, std::cos...) daha iyidir , çünkü daha kısadır ve kullanıcı tanımlı kayan nokta türleriyle ( bağımsız değişkene bağlı arama (ADL) aracılığıyla) çalışma yeteneğine sahiptir .

100 towi Jan 18 2013 at 16:34

Global olarak kullanmayın

Yalnızca global olarak kullanıldığında "kötü" olarak kabul edilir . Çünkü:

  • Programladığınız ad alanını karıştırırsınız.
  • Okuyucular, çok sayıda kullandığınızda belirli bir tanımlayıcının nereden geldiğini görmekte güçlük çekecektir using namespace xyz.
  • İçin de geçerlidir neyse olan diğer kaynak kod okuyucuları daha doğrudur bunu en sık okuyucu içindir: Kendinizi. Bir veya iki yıl sonra gelin ve bir göz atın ...
  • Sadece hakkında konuşursanız using namespace std, kaptığınız her şeyin farkında olmayabilirsiniz - ve başka bir tane eklediğinizde #includeveya yeni bir C ++ revizyonuna geçtiğinizde , farkında olmadığınız ad çatışmalarıyla karşılaşabilirsiniz.

Yerel olarak kullanabilirsiniz

Devam edin ve yerel olarak (neredeyse) özgürce kullanın. Bu, elbette, sizi tekrarlamaktan alıkoyar std::ve tekrar etmek de kötüdür.

Yerel olarak kullanmak için bir deyim

C ++ 03'te swap, sınıflarınız için bir işlev uygulamak için bir deyim - standart kod - vardı . Aslında bir yerel kullanmanız önerildi using namespace std- veya en azından using std::swap:

class Thing {
    int    value_;
    Child  child_;
public:
    // ...
    friend void swap(Thing &a, Thing &b);
};
void swap(Thing &a, Thing &b) {
    using namespace std;      // make `std::swap` available
    // swap all members
    swap(a.value_, b.value_); // `std::stwap(int, int)`
    swap(a.child_, b.child_); // `swap(Child&,Child&)` or `std::swap(...)`
}

Bu şu sihri yapar:

  • Derleyici std::swapfor value_, yani void std::swap(int, int).
  • Bir aşırı yük void swap(Child&, Child&)uyguladıysanız, derleyici onu seçecektir.
  • Eğer yoksa değil o aşırı yüklenme derleyici kullanır void std::swap(Child&,Child&)ve bu takas elinden geleni.

C ++ 11 ile artık bu kalıbı kullanmak için bir neden yok. Uygulaması, std::swappotansiyel bir aşırı yük bulmak ve onu seçmek için değiştirildi.

81 sth Sep 21 2009 at 10:23

Doğru başlık dosyalarını içe Eğer aniden gibi isimler var hex, left, plusya countda küresel kapsamda. Bu std::isimleri içerdiğinin farkında değilseniz, bu şaşırtıcı olabilir . Bu isimleri yerel olarak da kullanmaya çalışırsanız, bu biraz kafa karışıklığına yol açabilir.

Tüm standart şeyler kendi ad alanında ise, kodunuzla veya diğer kitaplıklarla ad çakışmaları konusunda endişelenmenize gerek yoktur.

52 MartinBeckett Sep 21 2009 at 10:13

Başka bir sebep de sürpriz.

Düşünmek cout << blahyerine görürsem std::cout << blah: Bu coutnedir? Bu normal coutmi? Özel bir şey mi?

49 AlexanderPoluektov Mar 29 2011 at 15:10

Deneyimli programcılar problemlerini çözen her şeyi kullanırlar ve yeni problemler yaratan şeylerden kaçınırlar ve tam da bu nedenle başlık-dosya seviyesinde kullanım-yönergelerinden kaçınırlar.

Deneyimli programcılar, kaynak dosyalarındaki adların tam olarak nitelendirilmesinden de kaçınmaya çalışırlar. Bunun küçük bir nedeni , iyi nedenler olmadıkça , daha az kod yeterliyken daha fazla kod yazmanın zarif olmamasıdır . Bunun önemli bir nedeni, bağımsız değişkene bağlı aramayı (ADL) kapatmaktır.

Bu iyi nedenler nelerdir? Bazen programcılar açıkça ADL'yi kapatmak isterken, diğer zamanlarda belirsizliği gidermek isterler.

Yani aşağıdakiler tamamdır:

  1. İşlev düzeyinde kullanım yönergeleri ve işlevlerin gerçekleştirimlerinde kullanım bildirimleri
  2. Kaynak dosyalar içinde kaynak dosya düzeyinde kullanım bildirimleri
  3. (Bazen) kaynak dosya düzeyinde kullanma yönergeleri
46 Oleksiy Aug 29 2013 at 16:44

I agree that it should not be used globally, but it's not so evil to use locally, like in a namespace. Here's an example from "The C++ Programming Language":

namespace My_lib {

    using namespace His_lib; // Everything from His_lib
    using namespace Her_lib; // Everything from Her_lib

    using His_lib::String; // Resolve potential clash in favor of His_lib
    using Her_lib::Vector; // Resolve potential clash in favor of Her_lib

}

In this example, we resolved potential name clashes and ambiguities arising from their composition.

Names explicitly declared there (including names declared by using-declarations like His_lib::String) take priority over names made accessible in another scope by a using-directive (using namespace Her_lib).

32 Yelonek Sep 21 2009 at 16:34

I also consider it a bad practice. Why? Just one day I thought that the function of a namespace is to divide stuff, so I shouldn't spoil it with throwing everything into one global bag.

However, if I often use 'cout' and 'cin', I write: using std::cout; using std::cin; in the .cpp file (never in the header file as it propagates with #include). I think that no one sane will ever name a stream cout or cin. ;)

27 gnasher729 Mar 14 2014 at 00:22

It's nice to see code and know what it does. If I see std::cout I know that's the cout stream of the std library. If I see cout then I don't know. It could be the cout stream of the std library. Or there could be an int cout = 0; ten lines higher in the same function. Or a static variable named cout in that file. It could be anything.

Now take a million line code base, which isn't particularly big, and you're searching for a bug, which means you know there is one line in this one million lines that doesn't do what it is supposed to do. cout << 1; could read a static int named cout, shift it to the left by one bit, and throw away the result. Looking for a bug, I'd have to check that. Can you see how I really really prefer to see std::cout?

It's one of these things that seem a really good idea if you are a teacher and never had to write and maintain any code for a living. I love seeing code where (1) I know what it does; and, (2) I'm confident that the person writing it knew what it does.

25 PreetSangha Sep 21 2009 at 10:14

It's all about managing complexity. Using the namespace will pull things in that you don't want, and thus possibly make it harder to debug (I say possibly). Using std:: all over the place is harder to read (more text and all that).

Horses for courses - manage your complexity how you best can and feel able.

20 RonWarholic Sep 21 2009 at 10:19

Consider

// myHeader.h
#include <sstream>
using namespace std;


// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // Uh oh
};

Note that this is a simple example. If you have files with 20 includes and other imports, you'll have a ton of dependencies to go through to figure out the problem. The worse thing about it is that you can get unrelated errors in other modules depending on the definitions that conflict.

It's not horrible, but you'll save yourself headaches by not using it in header files or the global namespace. It's probably all right to do it in very limited scopes, but I've never had a problem typing the extra five characters to clarify where my functions are coming from.

19 Kevin Sep 03 2016 at 03:06

A concrete example to clarify the concern. Imagine you have a situation where you have two libraries, foo and bar, each with their own namespace:

namespace foo {
    void a(float) { /* Does something */ }
}

namespace bar {
    ...
}

Now let's say you use foo and bar together in your own program as follows:

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

At this point everything is fine. When you run your program it 'Does something'. But later you update bar and let's say it has changed to be like:

namespace bar {
    void a(float) { /* Does something completely different */ }
}

At this point you'll get a compiler error:

using namespace foo;
using namespace bar;

void main() {
    a(42);  // error: call to 'a' is ambiguous, should be foo::a(42)
}

So you'll need to do some maintenance to clarify that 'a' meant foo::a. That's undesirable, but fortunately it is pretty easy (just add foo:: in front of all calls to a that the compiler marks as ambiguous).

But imagine an alternative scenario where bar changed instead to look like this instead:

namespace bar {
    void a(int) { /* Does something completely different */ }
}

At this point your call to a(42) suddenly binds to bar::a instead of foo::a and instead of doing 'something' it does 'something completely different'. No compiler warning or anything. Your program just silently starts doing something complete different than before.

When you use a namespace you're risking a scenario like this, which is why people are uncomfortable using namespaces. The more things in a namespace, the greater the risk of conflict, so people might be even more uncomfortable using namespace std (due to the number of things in that namespace) than other namespaces.

Ultimately this is a trade-off between writability vs. reliability/maintainability. Readability may factor in also, but I could see arguments for that going either way. Normally I would say reliability and maintainability are more important, but in this case you'll constantly pay the writability cost for an fairly rare reliability/maintainability impact. The 'best' trade-off will determine on your project and your priorities.

18 user2645752 Nov 09 2013 at 22:09

Using many namespaces at the same time is obviously a recipe for disaster, but using JUST namespace std and only namespace std is not that big of a deal in my opinion because redefinition can only occur by your own code...

So just consider them functions as reserved names like "int" or "class" and that is it.

People should stop being so anal about it. Your teacher was right all along. Just use ONE namespace; that is the whole point of using namespaces the first place. You are not supposed to use more than one at the same time. Unless it is your own. So again, redefinition will not happen.

18 DustinGetz Sep 21 2009 at 11:04
  1. You need to be able to read code written by people who have different style and best practices opinions than you.

  2. If you're only using cout, nobody gets confused. But when you have lots of namespaces flying around and you see this class and you aren't exactly sure what it does, having the namespace explicit acts as a comment of sorts. You can see at first glance, "oh, this is a filesystem operation" or "that's doing network stuff".

14 Carl Feb 12 2015 at 07:40

I agree with the others here, but I would like to address the concerns regarding readability - you can avoid all of that by simply using typedefs at the top of your file, function or class declaration.

I usually use it in my class declaration as methods in a class tend to deal with similar data types (the members) and a typedef is an opportunity to assign a name that is meaningful in the context of the class. This actually aids readability in the definitions of the class methods.

// Header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

and in the implementation:

// .cpp
Lines File::ReadLines()
{
    Lines lines;
    // Get them...
    return lines;
}

as opposed to:

// .cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    // Get them...
    return lines;
}

or:

// .cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    // Get them...
    return lines;
}
14 RohanSingh Apr 05 2015 at 19:56

A namespace is a named scope. Namespaces are used to group related declarations and to keep separate items separate. For example, two separately developed libraries may use the same name to refer to different items, but a user can still use both:

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    // ...
}

namespace Yourlib{
    class Stack{ /* ... */ };
    // ...
}

void f(int max) {
    Mylib::Stack<int> s1(max); // Use my stack
    Yourlib::Stack    s2(max); // Use your stack
    // ...
}

Repeating a namespace name can be a distraction for both readers and writers. Consequently, it is possible to state that names from a particular namespace are available without explicit qualification. For example:

void f(int max) {
    using namespace Mylib; // Make names from Mylib accessible
    Stack<int> s1(max); // Use my stack
    Yourlib::Stack s2(max); // Use your stack
    // ...
}

Namespaces provide a powerful tool for the management of different libraries and of different versions of code. In particular, they offer the programmer alternatives of how explicit to make a reference to a nonlocal name.

Source: An Overview of the C++ Programming Language by Bjarne Stroustrup

11 Nithin Dec 31 2014 at 15:00

An example where using namespace std throws a compilation error because of the ambiguity of count, which is also a function in algorithm library.

#include <iostream>
#include <algorithm>

using namespace std;

int count = 1;
int main() {
    cout << count << endl;
}
10 CryogenicNeo Apr 24 2018 at 00:15

It doesn't make your software or project performance worse. The inclusion of the namespace at the beginning of your source code isn't bad. The inclusion of the using namespace std instruction varies according to your needs and the way you are developing the software or project.

The namespace std contains the C++ standard functions and variables. This namespace is useful when you often would use the C++ standard functions.

As is mentioned in this page:

The statement using namespace std is generally considered bad practice. The alternative to this statement is to specify the namespace to which the identifier belongs using the scope operator(::) each time we declare a type.

And see this opinion:

There is no problem using "using namespace std" in your source file when you make heavy use of the namespace and know for sure that nothing will collide.

Some people had said that is a bad practice to include the using namespace std in your source files because you're invoking from that namespace all the functions and variables. When you would like to define a new function with the same name as another function contained in the namespace std you would overload the function and it could produce problems due to compile or execute. It will not compile or executing as you expect.

As is mentioned in this page:

Although the statement saves us from typing std:: whenever we wish to access a class or type defined in the std namespace, it imports the entirety of the std namespace into the current namespace of the program. Let us take a few examples to understand why this might not be such a good thing

...

Now at a later stage of development, we wish to use another version of cout that is custom implemented in some library called “foo” (for example)

...

Notice how there is an ambiguity, to which library does cout point to? The compiler may detect this and not compile the program. In the worst case, the program may still compile but call the wrong function, since we never specified to which namespace the identifier belonged.

8 Dr.Watson Sep 21 2009 at 10:34

I do not think it is necessarily bad practice under all conditions, but you need to be careful when you use it. If you're writing a library, you probably should use the scope resolution operators with the namespace to keep your library from butting heads with other libraries. For application level code, I don't see anything wrong with it.

8 Noname Oct 14 2014 at 00:30

I agree with others – it is asking for name clashes, ambiguities and then the fact is it is less explicit. While I can see the use of using, my personal preference is to limit it. I would also strongly consider what some others pointed out:

If you want to find a function name that might be a fairly common name, but you only want to find it in the std namespace (or the reverse – you want to change all calls that are not in namespace std, namespace X, ...), then how do you propose to do this?

You could write a program to do it, but wouldn't it be better to spend time working on your project itself rather than writing a program to maintain your project?

Personally, I actually don't mind the std:: prefix. I like the look more than not having it. I don't know if that is because it is explicit and says to me "this isn't my code... I am using the standard library" or if it is something else, but I think it looks nicer. This might be odd given that I only recently got into C++ (used and still do C and other languages for much longer and C is my favourite language of all time, right above assembly).

There is one other thing although it is somewhat related to the above and what others point out. While this might be bad practise, I sometimes reserve std::name for the standard library version and name for program-specific implementation. Yes, indeed this could bite you and bite you hard, but it all comes down to that I started this project from scratch, and I'm the only programmer for it. Example: I overload std::string and call it string. I have helpful additions. I did it in part because of my C and Unix (+ Linux) tendency towards lower-case names.

Besides that, you can have namespace aliases. Here is an example of where it is useful that might not have been referred to. I use the C++11 standard and specifically with libstdc++. Well, it doesn't have complete std::regex support. Sure, it compiles, but it throws an exception along the lines of it being an error on the programmer's end. But it is lack of implementation.

So here's how I solved it. Install Boost's regex, and link it in. Then, I do the following so that when libstdc++ has it implemented entirely, I need only remove this block and the code remains the same:

namespace std
{
    using boost::regex;
    using boost::regex_error;
    using boost::regex_replace;
    using boost::regex_search;
    using boost::regex_match;
    using boost::smatch;
    namespace regex_constants = boost::regex_constants;
}

I won't argue on whether that is a bad idea or not. I will however argue that it keeps it clean for my project and at the same time makes it specific: True, I have to use Boost, but I'm using it like the libstdc++ will eventually have it. Yes, starting your own project and starting with a standard (...) at the very beginning goes a very long way with helping maintenance, development and everything involved with the project!

Just to clarify something: I don't actually think it is a good idea to use a name of a class/whatever in the STL deliberately and more specifically in place of. The string is the exception (ignore the first, above, or second here, pun if you must) for me as I didn't like the idea of 'String'.

As it is, I am still very biased towards C and biased against C++. Sparing details, much of what I work on fits C more (but it was a good exercise and a good way to make myself a. learn another language and b. try not be less biased against object/classes/etc which is maybe better stated as less closed-minded, less arrogant, and more accepting.). But what is useful is what some already suggested: I do indeed use list (it is fairly generic, is it not ?), and sort (same thing) to name two that would cause a name clash if I were to do using namespace std;, and so to that end I prefer being specific, in control and knowing that if I intend it to be the standard use then I will have to specify it. Put simply: no assuming allowed.

And as for making Boost's regex part of std. I do that for future integration and – again, I admit fully this is bias - I don't think it is as ugly as boost::regex:: .... Indeed, that is another thing for me. There are many things in C++ that I still have yet to come to fully accept in looks and methods (another example: variadic templates versus var arguments [though I admit variadic templates are very very useful!]). Even those that I do accept it was difficult, and I still have issues with them.

8 EngineDev Aug 21 2016 at 05:55

From my experiences, if you have multiple libraries that uses say, cout, but for a different purpose you may use the wrong cout.

For example, if I type in, using namespace std; and using namespace otherlib; and type just cout (which happens to be in both), rather than std::cout (or 'otherlib::cout'), you might use the wrong one, and get errors. It's much more effective and efficient to use std::cout.

8 SwissFrank May 23 2019 at 05:05

It's case by case. We want to minimize the "total cost of ownership" of the software over its lifespan. Stating "using namespace std" has some costs, but not using it also has a cost in legibility.

People correctly point out that when using it, when the standard library introduces new symbols and definitions, your code ceases to compile, and you may be forced to rename variables. And yet this is probably good long-term, since future maintainers will be momentarily confused or distracted if you're using a keyword for some surprising purpose.

You don't want to have a template called vector, say, which isn't the vector known by everyone else. And the number of new definitions thus introduced in the C++ library is small enough it may simply not come up. There is a cost to having to do this kind of change, but the cost is not high and is offset by the clarity gained by not using std symbol names for other purposes.

Given the number of classes, variables, and functions, stating std:: on every one might fluff up your code by 50% and make it harder to get your head around. An algorithm or step in a method that could be taken in on one screenful of code now requires scrolling back and forth to follow. This is a real cost. Arguably it may not be a high cost, but people who deny it even exists are inexperienced, dogmatic, or simply wrong.

I'd offer the following rules:

  1. std is different from all other libraries. It is the one library everyone basically needs to know, and in my view is best thought of as part of the language. Generally speaking there is an excellent case for using namespace std even if there isn't for other libraries.

  2. Never force the decision onto the author of a compilation unit (a .cpp file) by putting this using in a header. Always defer the decision to the compilation unit author. Even in a project that has decided to use using namespace std everywhere may fine a few modules that are best handled as exceptions to that rule.

  3. Even though the namespace feature lets you have many modules with symbols defined the same, it's going to be confusing to do so. Keep the names different to the extent possible. Even if not using the namespace feature, if you have a class named foo and std introduces a class named foo, it's probably better long-run to rename your class anyway.

  4. An alternative to using namespaces is to manually namespace symbols by prefixing them. I have two libraries I've used for decades, both starting as C libraries, actually, where every symbol is prefixed with "AK" or "SCWin". Generally speaking, this is like avoiding the "using" construct, but you don't write the twin colons. AK::foo() is instead AKFoo(). It makes code 5-10% denser and less verbose, and the only downside is that you'll be in big trouble if you have to use two such libraries that have the same prefixing. Note the X Window libraries are excellent in this regard, except they forgot to do so with a few #defines: TRUE and FALSE should have been XTRUE and XFALSE, and this set up a namespace clash with Sybase or Oracle that likewise used TRUE and FALSE with different values! (ASCII 0 and 1 in the case of the database!) One special advantage of this is that it applies seemlessly to preprocessor definitions, whereas the C++ using/namespace system doesn't handle them. A nice benefit of this is that it gives an organic slope from being part of a project to eventually being a library. In a large application of mine, all window classes are prefixed Win, all signal-processing modules Mod, and so on. There's little chance of any of these being reused so there's no practical benefit to making each group into a library, but it makes obvious in a few seconds how the project breaks into sub-projects.

7 AugustKarlstrom Apr 11 2013 at 21:22

With unqualified imported identifiers you need external search tools like grep to find out where identifiers are declared. This makes reasoning about program correctness harder.

7 MathGladiator Sep 21 2009 at 10:15

It depends on where it is located. If it is a common header, then you are diminishing the value of the namespace by merging it into the global namespace. Keep in mind, this could be a neat way of making module globals.

7 adn.911 Nov 30 2017 at 23:24

This is a bad practice, often known as global namespace pollution. Problems may occur when more than one namespace has the same function name with signature, then it will be ambiguous for the compiler to decide which one to call and this all can be avoided when you are specifying the namespace with your function call like std::cout . Hope this helps. :)

6 NoneyoGetit Jun 28 2013 at 03:33

To answer your question I look at it this way practically: a lot of programmers (not all) invoke namespace std. Therefore one should be in the habit of NOT using things that impinge or use the same names as what is in the namespace std. That is a great deal granted, but not so much compared to the number of possible coherent words and pseudonyms that can be come up with strictly speaking.

I mean really... saying "don't rely on this being present" is just setting you up to rely on it NOT being present. You are constantly going to have issues borrowing code snippets and constantly repairing them. Just keep your user-defined and borrowed stuff in limited scope as they should be and be VERY sparing with globals (honestly globals should almost always be a last resort for purposes of "compile now, sanity later"). Truly I think it is bad advice from your teacher because using std will work for both "cout" and "std::cout" but NOT using std will only work for "std::cout". You will not always be fortunate enough to write all your own code.

NOTE: Don't focus too much on efficiency issues until you actually learn a little about how compilers work. With a little experience coding you don't have to learn that much about them before you realize how much they are able to generalize good code into something something simple. Every bit as simple as if you wrote the whole thing in C. Good code is only as complex as it needs to be.