
On Sun, Nov 18, 2012 at 2:03 PM, Jeffrey Lee Hellrung, Jr. < jeffrey.hellrung@gmail.com> wrote:
On Sun, Nov 18, 2012 at 7:22 AM, Edward Diener <eldiener@tropicsoft.com>wrote:
On 11/16/2012 12:32 AM, Jeffrey Lee Hellrung, Jr. wrote:
On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener@tropicsoft.com> **wrote:
I have found something like this to be helpful, when working with
multiple compilers:
#include <boost/config.hpp> #if defined(BOOST_NO_NULLPTR) #define BOOST_XXX_NULLPTR 0 #else #define BOOST_XXX_NULLPTR nullptr #endif
where XXX is some local name for my own use. And then use BOOST_XXX_NULLPTR in places where a null pointer is needed.
Would this be a candidate for a BOOST_NULLPTR macro in the config library instead ?
Might it be better to just offer a (albeit imperfect) nullptr emulation if not supplied by the compiler? For example, [1].
- Jeff
I agree that you are right.
If the nullptr emulation has less problems than using 0 it would seem worthwhile. That appears to be easily the case. Both are of course imperfect but it appears that a nullptr emulation is far less imperfect. The question then is who is going to do it and support it, given that it will most probably be obsolete in the near future as more compilers implement features of C++11. Unless someone steps up to do it ( and I am not that person due to, for one, already being behind in getting TTI into Boost ) it will not be done and then using 0 is at least a second best solution.
In my own current use of nullptr in cross-compiler code for Boost using 0 is adequate for my means in the few instances where I am using nullptr. So my suggestion in my OP is adequate for me right now but may well not be adequate for others or for future usage on compilers which do not support nullptr.
I'll post something this week and if it's ultimately decided to be included in, e.g., boost/utility, I don't have a problem supporting it.
First go at it: /*** BEGIN NULLPTR DEFINITION ***/ #include <boost/config.hpp> #ifndef BOOST_NO_NULLPTR #include <cstddef> namespace boost { typedef std::nullptr_t nullptr_t; } // namespace boost #else // #ifndef BOOST_NO_NULLPTR #include <ostream> namespace boost { struct nullptr_t { template< class T > operator T * () const { return static_cast< T * >(0); } template< class T, class C > operator T C:: * () const { return static_cast< T C:: * >(0); } #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS explicit operator bool () { return false; } #else // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS private: struct _boost_explicit_operator_bool_struct { }; typedef int (_boost_explicit_operator_bool_struct::*_boost_explicit_operator_bool_result_type); public: operator _boost_explicit_operator_bool_result_type () const { return 0; } #endif // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS // Must be public in order for nullptr_t to be POD. void * _boost_nullptr_sizeof; #ifndef BOOST_NO_DELETED_FUNCTIONS void operator & () const = delete; #else // #ifndef BOOST_NO_DELETED_FUNCTIONS private: void operator & () const; #endif // #ifndef BOOST_NO_DELETED_FUNCTIONS }; boost::nullptr_t const nullptr = { 0 }; inline bool operator==(boost::nullptr_t, boost::nullptr_t) { return true; } inline bool operator!=(boost::nullptr_t, boost::nullptr_t) { return false; } inline std::ostream & operator<<(std::ostream & o, boost::nullptr_t) { return o << static_cast< void * >(0); } } // namespace boost using boost::nullptr; #endif // #ifndef BOOST_NO_NULLPTR /*** END NULLPTR DEFINITION ***/ #include <cassert> #include <boost/implicit_cast.hpp> #include <boost/static_assert.hpp> struct X { }; int main(int argc, char * argv[]) { BOOST_STATIC_ASSERT( sizeof( nullptr ) == sizeof( void * ) ); assert(!static_cast< bool >(nullptr)); assert(!nullptr); assert(boost::implicit_cast< void * >(nullptr) == 0); assert(boost::implicit_cast< int * >(nullptr) == 0); assert(boost::implicit_cast< int X::* >(nullptr) == 0); //assert(nullptr == static_cast< void * >(0)); //assert(nullptr != &argc); return 0; } Unfortunately, the assertions that are commented out in main trigger an ICE on MSVC9 (yeah, big surprise); it's possible I did something wrong, but in the event that I didn't, if we can find a workaround to get such expressions to work, that'd be great (I tried explicitly defining operator== and operator!= out-of-line, and that didn't help). Also, I only tested this on MSVC9 (for now). Comments? - Jeff