Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a using-directive in a detail namespace problematic?

Consider this library header:

#include<vector>
#include<algorithm>
#include<iostream>

namespace Lib {
  namespace detail {
    using namespace std;

    template<class T>
    void sort_impl(istream &in,ostream &out) {
      vector<T> v;
      {
        int n;
        in >> n;
        v.resize(n);
      }
      for(auto &i : v) cin >> i;

      sort(v.begin(),v.end());
      for(auto i : v) out << i << endl;
    }
  }

  inline void sort_std() {
    detail::sort_impl<int>(std::cin,std::cout);
  }
}

Does the detail namespace successfully isolate the clients of the library (and the rest of library's implementation) from the using-directive in this example? I'm not interested in the discussion at Why is "using namespace std" considered bad practice?, even though some of the arguments apply even to "well contained" using-directives.

Note that there are two existing questions concerning the same situation but with using-declarations:

  • Using declarations in private namespaces in header files
  • Elegant way to prevent namespace poisoning in C++ (whose one answer is really an answer to the "bad practice" question above)

This could be combined with either of them, but the editing would be severe.

like image 667
Davis Herring Avatar asked Sep 12 '17 04:09

Davis Herring


People also ask

What is problematic about putting a using namespace directive at the start of your code?

The problem with putting using namespace in the header files of your classes is that it forces anyone who wants to use your classes (by including your header files) to also be 'using' (i.e. seeing everything in) those other namespaces. However, you may feel free to put a using statement in your (private) *.

Why should you never place a using namespace directive inside of a header file?

However you'll virtually never see a using directive in a header file (at least not outside of scope). The reason is that using directive eliminate the protection of that particular namespace, and the effect last until the end of current compilation unit.

What is using directive in namespace?

A using directive provides access to all namespace qualifiers and the scope operator. This is accomplished by applying the using keyword to a namespace identifier.

Why is using namespace a bad practice?

While this practice is okay for example code, pulling in the entire std namespace into the global namespace is not good as it defeats the purpose of namespaces and can lead to name collisions. This situation is called namespace pollution.


2 Answers

You pollute your own detail namesapce, but not the Lib or global namespaces. So assuming a responsible adult is using your library, they won't have unintentional name collisions:

#include <vector>

namespace Lib {
  namespace detail {
    using namespace std;
  }
}

using namespace Lib;

int main() {
    vector<int> v; // This is an error, vector not declared in this scope
}
like image 155
StoryTeller - Unslander Monica Avatar answered Sep 24 '22 01:09

StoryTeller - Unslander Monica


No, the detail namespace will not isolate clients from the nested using directive. [namespace.udir] is quite explicit about that

A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup, the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]

A little example

#include <iostream>

namespace foo {
    namespace detail {
        using namespace std;
    }
}

int main()
{
    foo::detail::cout << "Hello World!\n";

    // nothing is stopping me from doing that
    using namespace foo::detail;
    cout << "Hello World!\n";
}

STL gives a nice explanation of how name lookup works in his video Core C++, 1 of n.

like image 44
Henri Menke Avatar answered Sep 22 '22 01:09

Henri Menke