14

I have C++03 code that looks like this:

#include <boost/tr1/unordered_map.hpp>
...
std::tr1::unordered_map<std::string, int> mystuff;
...

I started to wonder that i would suffer later if/when i convert my code to C++11, which (i guess) doesn't have std::tr1::unordered_map but has std::unordered_map instead. So i came up with the following hack:

namespace std
{
    using namespace ::std::tr1;
}
...
std::unordered_map<std::string, int> mystuff; // no tr1 now!
...

Is it legal (maybe importing stuff into std is forbidden)? Will it make it easier to port/interoperate with C++11 code?

anatolyg
  • 23,079
  • 7
  • 51
  • 113
  • 1
    My compiler (VS2010) still understands `std::tr1` even though everything now also exists in `std`. – Benj May 24 '12 at 10:56

4 Answers4

16

You should not touch the std namespace: even if it works now, it can cause severe headaches later (with a new version of the compiler, on a different compiler, etc).

Update: Quote from the standard (C++ 2003, Section 17.4.3.1 "Reserved names") (found here):

It is undefined for a C++ program to add declarations or definitions to namespace std or namespaces within namespace std unless otherwise specified. A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined type of external linkage and unless the specialization meets the standard library requirements for the original template. [emphasis mine]

Attila
  • 26,065
  • 3
  • 41
  • 52
  • 1
    I think the only interesting answers are those backed by some facts - like "what the standard says about that". – akappa May 24 '12 at 11:11
  • @akappa: unless those are trivia ;) Now, of course, what is and is not trivia is quite subjective. For example, I consider this to be trivial, while you apparently do not! – Matthieu M. May 24 '12 at 11:33
  • @MatthieuM.: this site is full of trivial questions, i.e., questions whose answer is trivial. So, either we decide to not answer to those question, or we concur that "triviality" does not mean anything in this site, only correctness and being factual does. – akappa May 24 '12 at 12:01
  • @akappa: I would propose a middleway: if you think it is trivial and does not warrant a quote, do so, others will judge and you'll be able to adapt :) – Matthieu M. May 24 '12 at 12:11
  • @MatthieuM. - this is exactly what happened in this case – Attila May 24 '12 at 12:24
  • A shame that the standard forbids it, considering if you limit it to importing only (not defining) there's [some nice stuff you can do](http://stackoverflow.com/questions/8747005/backporting-nullptr-to-c-pre-c0x-programs). Oh well, I at least don't let `-pedantic` get in the way of forwards-compatibility. – Luis Machuca Jul 21 '12 at 22:46
7

Importing stuff into ::std is forbidden by C++11 17.6.4.2.1:

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified.

Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
3

I think this question is very similar to what you are asking about.

In particular, I like the answer which says "use autoconf to detect symbols availability and then use conditional defines to alias the right namespace with a given name".

Community
  • 1
  • 1
akappa
  • 9,494
  • 3
  • 37
  • 53
1

This kind of portability should only be attempted if you have a proof that you cannot support a particular library in a clearer way, and ideally you should surround it with #ifdefs specific to that particular environment.

The point of tr1 was to isolate your std from the stuff in tr1.

Jirka Hanika
  • 12,574
  • 3
  • 39
  • 68