views:

72

answers:

3

It is widely known that adding declarations/definitions to namespace std results in undefined behavior. The only exception to this rule is for template specializations.

What about the following "hack"?

#include <iostream>

namespace std_
{
  void Foo()
  {
    std::clog << "Hello World!" << std::endl;
  }

  using namespace std;
}

int main()
{
  namespace std = std_;

  std::Foo();
}

Is this really well-defined as far as the standard is concerned? In this case, I'm really not adding anything to namespace std, of course. Every compiler I've tested this on seems to happily swallow this.


Before someone makes a comment resembling "why would you ever do that?" -- this is just to satisfy my curiosity...

+2  A: 

Redefining std as an alias is okay, as long as you are not in the global declarative region:

In a declarative region, a namespace-alias-definition can be used to redefine a namespace-alias declared in that declarative region to refer only to the namespace to which it already refers.

Since you define the alias in main(), it shadows the global std name. That's why this works, should work, and is perfectly fine according to the standard. You're not adding anything to the std namespace, and this "hack" only serves to confuse the human reader of the code.

Thomas
A function body is a new declarative region.
Charles Bailey
Thomas, see Charles' comment. I'm doing this in a new region.
tlenp
Thanks, edited.
Thomas
I can only think of one legitimate use for this right off the bat. Modifying the behavior of some header-only library code without actually touching the library file itself. Probably only useful for testing, though.
tlenp
+1  A: 

Inside main, after the namespace alias definition, std refers to the alias std for the std_ namespace. The "usual" std namespace is hidden, much as a function local variable would hide a global variable with the same name.

Charles Bailey
A: 

You're not adding anything to std::. You're adding to std_::, then declaring an alias named std::.

I never knew that there is a rule you can't add to std::. Is that correct? If so, I'm guessing that the rule only exists to reserve the namespace for future expansion. So you really don't have to hack anything if you really want to augment std::.

Someone post if you know of a compiler that does NOT allow such a thing...

John