More or less what the title suggests. While I'm not yet using C++0x I'd like to be prepared for when it happens, and I'd also like to reduce the amount of code I have to rewrite to use some of its facilities. That way I can get backwards and forwards compatibility in one go.
One of the most interesting ones I have found is nullptr
, which I've been using more often recently.
After checking the "Official workaround" and Meyer's suggestion, I decided that I'd like to use this in both my C++ and future C++0x programs. The second part is simple -- being a keyword, nullptr
will simply be supported. But the first part is causing me some discomfort.
The Meyers proposal functions like this:
class nullptr_t { // ← this is my issue
// definition of nullptr_t
} nullptr = { };
The problem with that proposal is that it declares the type to be declared as std::nullptr_t
as required by C++0x. Which means for the workaround to "feel native" it has to be done by reopening the std::
namespace to add a type. I have the understanding that is illegal to do in a C++ program (unlike adding specializations which is apparently frown-and-let-go-with-a-warning).
I want to use nullptr
in a comfortable AND legal way in a C++ program. One option I had thought of was declaring the type in another namespace and then bring it in using using
:
namespace mylibrary {
class nullptr_t {
....
} nullptr = { };
// end namespace
}
// These would have to go in the header file.
using mylibrary::nullptr;
using mylibrary::nullptr_t; // apparently this is necessary as well?
Would this be the correct way to make it work? It would force using
directives, which also forces a specific order of #include
directives as well. Would I be right to expect that no pre-C++0x code would request the type nullptr_t
with namespace (as a function argument type, for example)? Would it actually work "feeling native" if it is done this way?
As an addendum, is it a welcomed or frowned upon thing to try and backport some nifty C++0x things to C++ for better compatibility and coding? In the meantime I have integrated this solution and other ones I'm working on in a piece of software to be released.
Unless you can think of a reason you need to declare another object of type
nullptr_t
(I can't), I would hide the type away and putnullptr
in the global namespace to mimic a keyword as closely as possible:The main reason you are not allowed to add things to
namespace std
is so you don't mess things up which are already there. This could otherwise easily be done. Something I found in the past were multiple definitions for output operators for containers instantiated with a built-in type likestd::vector<int>
. However,nullptr_t
isn't defined in this namespace and adding atypedef
should be pretty harmless. That is, I would definenullptr_t
in a different namespace thannamespace std
and then add atypedef
fornullptr_t
tonamespace std
. The variablenullptr
needs to be declared at global scope anyway as it is used unqualified in C++2011.Whether the type
std::nullptr_t
is needed depends on whether you are interest in adding the signatures using this type. For example,std::shared_ptr<T>
can be compared againstnullptr
. For this, it is necessary to add suitable overloads which mention the typestd::nullptr_t
(or use some other name for this type).