PiJ
PiJ

Reputation: 153

Extending namespace std with backported types and templates from newer C++ standards

Currently we work on a library that is allowed to use C++11/14 features and types when possible but must fallback to a C++03 implementation otherwise. Users and developers of this library are encouraged to use types and templates from namespace std.

Problems arise when using types from namespace std introduced by newer versions of the C++ Standard which are not shipped with the compiler used. One suggested option is to provide 'backports' for certain types that do not rely on new language features into namespace std as part of our library code, e.g. Fixed width integer types:

//file: std_backport.h

namespace std_backport {
    typedef char  int8_t;  //for platforms where 'char' is 8 bit
    typedef short int16_t; //for platforms where 'short' is 16 bit
    //[and so on]
}

//enter 'sacred' territory and introduce the types to namespace std
namespace std {
    using namespace ::std_backport;
}

Another example would be the tuple type which is provided by VS2010 in the technical report:

//file std_tuple_backport.h
#include <tr1/tuple>                //std::tr1::tuple

namespace std {
    using ::std::tr1::tuple;
}

Of course we have to provide checks to enable/disable the inclusion of those files according to the compilers used.

I did some research on this matter and aware of the fact, that extending the namespace std like this is undefined behavior I wanted to drop this idea. But than I came across this answer which states in #4:

Putting anything in std namespace is an "undefined behaviour". That means the specification does not say what will happen. But if you know that on particular platform the standard library does not define something, just go ahead and define it. [...]

So my questions are:

Upvotes: 2

Views: 358

Answers (1)

eerorika
eerorika

Reputation: 238351

Can please someone clarify to me what exactly is meant by 'undefined behavior' in this case?

Same as in every other case. The standard doesn't guarantee any behaviour.

The program might fail to compile, succesfully compile but crash, not crash and have expected output, or unexpected output depending on any variable such as the compiler, the CPU architechture or the phase of the moon. As far as the standard is concerned.

Is providing C++11/14 compatibility like this considered 'bad practice' even if we just provide types from a newer standard?

If I care about standard compliance of the program - and I often do, then I consider it a bad practice.

What would be an alternative or even better way to achieve this kind of code compatibility without having to define everything from namespace std in an own namespace and use this instead of namespace std?

You don't need to define everything from std. Simply define the missing features in another namesace (or use a third party implementation), and use the existing features from the std namespace.

Upvotes: 1

Related Questions