BeppeNanoso
BeppeNanoso

Reputation: 105

Extending namespace std to implement make_unique when using C++11

I came across a codebase that is fixed on C++11 features but implements std::make_unique. That is been done extending namespace std to add the feature if C++14 is not use, i.e. wrapping the implementation around

#if defined(__cplusplus) && __cplusplus < 201402L

namespace std {
  ...
}

#endif

I know that is undefined behavior to extend namespace std (with some exception). Is the case above still acceptable or should it be avoided in any case?

Upvotes: 7

Views: 283

Answers (5)

Jarod42
Jarod42

Reputation: 217398

As it is undefined to put yourself that definition in namespace std

I would use:

#if __cplusplus < 201402L
namespace extended_std /* or more appropriate name */
{
    namespace std
    {
        // make_unique
    }
}

using namespace extended_std; // So you can use std::make_unique
                              // but not ::std::make_unique nor ADL usage :( .
#endif

Upvotes: 0

Davis Herring
Davis Herring

Reputation: 39838

No, this is forbidden—even though, via

#define make_unique ? ? ?

a conforming C++11 program can be quite sure that the library never mentions the name (outside of a stringization) and would thus be unable to detect the extension.

Upvotes: 8

user10957435
user10957435

Reputation:

The only time it is okay to extend namespace std is template specialization:

The only case where it is OK to add a definition into the std namespace is specialization of a template that already exists in the namespace and to explicitly instantiate a template. However, only if they depend on a user defined type.

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490168

The approach I've taken in this case is slightly different:

#if __cplusplus < 201402L

namespace std14 {
  ...
}

#else
     using namespace std14 = std;
#endif

Then you write your code like:

auto foo = std14::make_unique<T>(whatever);

...and for now it'll use your implementation of make_unique, but when/if you start using a C++14 compiler, it'll use the implementation provided by the compiler.

Upvotes: 5

Acorn
Acorn

Reputation: 26076

Is the case above still acceptable or should it be avoided in any case?

Whether relying on UB is acceptable or not depends on your environment, your users, your policies, etc.

In practical terms, whatever UB means depends on your implementation.

Upvotes: 0

Related Questions