18

Is it acceptable to add types to the std namespace. For example, I want a TCHAR-friendly string, so is the following acceptable?

#include <string>

namespace std
{
    typedef basic_string<TCHAR> tstring;
}

Or should I use my own namespace?

Rob
  • 76,700
  • 56
  • 158
  • 197

7 Answers7

19

Only specializations are allowed. So for example, you are allowed to specialize std::numeric_limits for your type. And this of course must happen in namespace std::. But your typedef isn't a specialization so that's causing undefined behavior.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • According to [this answer](http://stackoverflow.com/a/2684544/1468366), `swap` implementations shouldn't go into `std` any more, as algorithms using `swap` should rely on argument-dependent lookup. – MvG Feb 15 '13 at 21:55
  • @MvG that answer is right. My example isn't and wasn't good. I will replace it. – Johannes Schaub - litb Feb 15 '13 at 23:01
  • Why is `numeric_limits` any different from `swap` in this regard? – Dan Nissenbaum Jan 27 '14 at 14:29
  • @DanNissenbaum i don't know the rules for `swap`. If it is not allowed to specialize it, that may be because *ADL* provides a superior alternative – Johannes Schaub - litb Jan 27 '14 at 17:52
  • If I understand a potential interpretation of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1289.html (linked from a comment beneath http://stackoverflow.com/q/21384604/368896), then perhaps the standard states that `Unless otherwise specified, no global or non-member function in the standard library shall use a function from another namespace which is found through argument-dependent name lookup (3.4.2 [basic.lookup.koenig])` - in which case, one **must** place *typical* functions in `std`, but perhaps `swap` is a special-case 'primitive' for which ADL is *allowed* as an exception? – Dan Nissenbaum Jan 27 '14 at 18:18
  • @DanNissenbaum i think that is very likely. Since you are not allowed to put overloads into `std` itself, and you cannot partially specialize a function template (and so you cannot provide a swap for your own templated container as a specialization), you must be allowed to use ADL here. – Johannes Schaub - litb Jan 27 '14 at 18:32
  • ... Wouldn't the same reasoning apply for *any* function (such as the `numeric_limits` you use as an example)? – Dan Nissenbaum Jan 27 '14 at 18:51
  • 1
    @Dan numeric_limits is not a function template, so it will not apply. You can write `template struct numeric_limits> { ... };` perfectly fine. – Johannes Schaub - litb Jan 27 '14 at 19:04
18

No ... part of the point of a namespace is to prevent name collisions on upgrade.

If you add things to the std namespace, then your code might break with the next release of the library if they decide to add something with the same name.

Rob Walker
  • 46,588
  • 15
  • 99
  • 136
  • 3
    It also violates the standard, afaik. The std namespace is sacred. (Apart from specializations of existing std functions) :) – jalf Nov 26 '08 at 15:14
18

[C++11: 17.6.4.2.1/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. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
3

You should use your own namespace as adding code to the standard library will only confuse the users that will look online for informations about that addition.

All that is in std should be only the standard library and nothing else.

Klaim
  • 67,274
  • 36
  • 133
  • 188
  • I'm not convinced it will confuse users - in fact they may expect a std::basic_string type to be in std. Tough call I think. – Rob Nov 26 '08 at 14:13
  • 1
    No, Klaim is correct. You should not add anything to the std namespace. Users may *expect* basic_string to be in std, but it is NOT part of the std library and they will not find anything on it in the published documentation for a given std implementation. The correct way is to use your own ns. – Zach Burlingame Nov 26 '08 at 14:36
  • I had to look this one up. `basic_string` is actually defined as part of the `std` namespace on page 384 of ISO/IEC 14882:1998. – Zhro Feb 10 '16 at 00:09
2

This is an interesting question because it's completely subjective to the project and the engineers' accepted coding standards.

For a single programmer, why not... just be careful.

For teams, make a standard...

For a cross-platform project, hell yeah.

Otherwise, nawdawg.

jeffery
  • 109
  • 1
  • 6
2

Officially, the standard says that's "undefined behaviour", and all kinds of nasty things can happen.

In practice, it will work fine, but you still shouldn't do it. What does it buy you, other than confusing people that something is provided by the compiler?

Chris Jefferson
  • 7,225
  • 11
  • 43
  • 66
2

I totally agree with other answers saying that you should put your types in your own namespace to avoid unfortunate name collisions.

However, I wanted to precise that sometimes, you can (and should !) add stuff in the std namespace. This is the case for template specializations of the std::swap method for example, which are used to provide a uniform way to swap objects. For more information on this matter, you can read about the non-throwing swap idiom.

Luc Touraille
  • 79,925
  • 15
  • 92
  • 137