Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I tried to write a nullptr_t class based on the official proposal to be used in C++03 only. The only differences with the proposal are that we can compare two nullptr_t instances and that it is convertible to bool via an overload to void* to avoid unwanted behaviour such as int a = nullptr; for example. Here is the class:

const class nullptr_t
{
    public:

        // Return 0 for any class pointer
        template<typename T>
        operator T*() const
        {
            return 0;
        }

        // Return 0 for any member pointer
        template<typename T, typename U>
        operator T U::*() const
        {
            return 0;
        }

        // Used for bool conversion
        operator void*() const
        {
            return 0;
        }

        // Comparisons with nullptr
        bool operator==(const nullptr_t&) const
        {
            return true;
        }
        bool operator!=(const nullptr_t&) const
        {
            return false;
        }

    private:

        // Not allowed to get the address
        void operator&() const;

} nullptr = {};

I would like to know if there is any actual flaw in this completed implementation or if there is a difference in the behaviour compared to the C++11 type std::nullptr_t besides the namespace that I can't see.

share|improve this question

2 Answers 2

up vote 7 down vote accepted

At the moment, your implementation allows

auto& p = nullptr;

This is forbidden in C++11 as nullptr is an rvalue. You also do not allow the following:

auto p = nullptr;
auto pp = &p;

While C++11 does allow it. You are also missing overloads for comparison operators.

A simple workaround would be to remove the operator& overload and add a macro:

#define nullptr (nullptr_t())

Also, I'd generally use struct X { ... } const x; instead of const struct X { ... } x;.

share|improve this answer

Another thing I forgot at the time is that the standard specifies that sizeof(nullptr) shall be equal to sizeof(void*).

3.9.1 - Fundamental types

3.9.1.10 A value of type std::nullptr_t is a null pointer constant (4.10). Such values participate in the pointer and the pointer to member conversions (4.10, 4.11). sizeof(std::nullptr_t) shall be equal to sizeof(void*).

So technically speaking, I should have added padding to my class:

class nullptr_t
{
    // To ensure the size
    // Should be correctly aligned
    void* padding;
    // ...
} const nullptr;
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.