Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scope of using declaration within a namespace

Is it safe (and correct) in a C++ header file to use the using declaration within a namespace as follows:

#include <boost/numeric/ublas/vector.hpp> namespace MyNamespace {     using boost::numeric::ublas::vector;     vector MyFunc(vector in); } 

I.e. is the "using boost::numeric::ublas::vector" properly contained within the MyNamespace block, or will this pollute the namespace of any file that includes this header?

like image 946
Brett Ryland Avatar asked May 30 '11 11:05

Brett Ryland


People also ask

What is the scope of a namespace?

A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.

What can be declared inside a namespace?

A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it. Multiple namespace blocks with the same name are allowed. All declarations within those blocks are declared in the named scope.

What is the use of using declaration in C++?

A using declaration in a definition of a class A allows you to introduce a name of a data member or member function from a base class of A into the scope of A .

Which is the correct method for declaring a namespace?

Which is the correct syntax of declaring a namespace? namespace B{ int i; };


1 Answers

No, it is not safe - it won't pollute another namespace, but it is dangerous for other reasons:

A using directive will import anything that is currently visible by the name you specify into the namespace where you use it. While your using will only be visible to users of MyNamespace, other things from "outside" will be visible to your using declaration.

So how is this dangerous when used in a header? Because it will import things that are visible at the point of the declaration, the exact behavior will depend on the order of headers you include before the declaration (There might be different things visible from boost::numeric::ublas::vector). Since you cannot really control which headers are included before your header (nor should you be! headers should be self-sufficient!), this can lead to very strange problems where your function will find one thing in one compilation unit, and another in the next.

As a rule of thumb, using declarations should only be used after all includes in a .cpp file. There's also an item on this exact issue in the book "C++ Coding Standards" by Sutter and Alexandrescu (Item 59). Here's a quote:

But here's the common trap: Many people think that using declarations issued at namespace level (...) are safe. They are not. They are at least as dangerous, and in a subtler and more insidious way.

Even when it's unlikely that the name you are using doesn't exist anywhere else (as is probably the case here), things can get ugly: In a header, all declarations should be fully qualified. This is pain, but otherwise, strange things can happen.

Also see Migrating to Namespaces, Using-declarations and namespace aliases and Namespace Naming for examples and the problem described in-depth.

like image 173
ltjax Avatar answered Oct 02 '22 17:10

ltjax