7

我尝试了 nullptr 的官方实现

我知道编译器支持 nullptr 和 std::nullptr_t,这个实现是没有意义的。我只是想研究 C++。

GCC4.9.1 在我的 PC 上一切正常,-std=c++03 和 -std=c++11,甚至成功在线 @ideone.com GCC4.3.2。

但在 VS2013 第 125 行出现 error2440,转换失败

error C2440: "initialize": cannot convert "const <unnamed-type-my_nullptr>" to "int (__thiscall Test::* )(void) const" in line125

>

#include <iostream>
#include <cassert>

// The Official proposal
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
const // this is a const object... 
class {
public:
    template<class T> // convertible to any type 
    operator T*() const // of null non-member 
    {
        return 0;
    } // pointer... 

    template<class C, class T> // or any type of null 
    operator T C::*() const // member pointer... 
    {
        return 0;
    }

private:
    void operator&() const; // whose address can't be taken 
} my_nullptr = {}; // and whose name is nullptr


struct Test123 {
    int ABCD, ABC, AB;
    int A;
    int BA, CBA, DCBA;
    struct XYZ {
        char X, Y, Z, W;
    };
    struct {
        int B, C, D;
    };
} test123;


class Test {
    int ABCD;
public:
    void method(void){}

    Test(int val) :ABCD(val){}
    int getABCD(void) const { return ABCD; }
    int get2ABCD(void) const { return ABCD * 2; }
    int get3ABCD(void) const { return ABCD * 3; }
} test(0123);


int main(int argc, char* argv[])
{

    // TEST_my_nullptr
    {
        int a = 321, *p = my_nullptr;
        assert(p == my_nullptr);
        assert(my_nullptr == p);

        p = &a; *p = 0123;
        assert(p != my_nullptr);
        assert(my_nullptr != p);

        p = my_nullptr;

        int(*mainptr)(int argc, char** argv) = my_nullptr;
        assert(mainptr == my_nullptr);
        assert(my_nullptr == mainptr);
    }


    // TEST_my_nullptr_const
    {
        const int a = 321, *p = my_nullptr;
        assert(p == my_nullptr);
        assert(my_nullptr == p);

        p = &a;
        assert(p != my_nullptr);
        assert(my_nullptr != p);

        const int** ptr = my_nullptr;

        assert(ptr == my_nullptr);
        assert(my_nullptr == ptr);

        ptr = &p;
        assert(ptr != my_nullptr);
        assert(my_nullptr != ptr);
        assert(*ptr != my_nullptr);
        assert(my_nullptr != *ptr);

    }


    // TEST_my_nullptr_member
    {
        int Test123::*pINT = my_nullptr;
        assert(pINT == my_nullptr);
        assert(my_nullptr == pINT);

        pINT = &Test123::ABCD;
        assert(pINT != my_nullptr);
        assert(my_nullptr != pINT);

        test123.*pINT = 0123;

        const int Test123::*pCINT = my_nullptr;
        assert(pCINT == my_nullptr);
        assert(my_nullptr == pCINT);

        pCINT = &Test123::ABCD;
        assert(pCINT != my_nullptr);
        assert(my_nullptr != pCINT);

        assert(test123.*pCINT == test123.*pINT);
    }

    // TEST_my_nullptr_Function
    {
        void (Test::*pm)(void) = &Test::method;

        pm = my_nullptr;

       > int (Test::*pABCD)(void) const = my_nullptr; // This Fxxk Line In VS2013

        pABCD = &Test::getABCD;

        int a1 = (test.*pABCD)();

        pABCD = &Test::get2ABCD;
        int a2 = (test.*pABCD)();

        pABCD = &Test::get3ABCD;
        int a3 = (test.*pABCD)();

        assert(a1 + a2 == a3);
    }

    std::cout << "All Tests for my_nullptr Passed!" << std::endl;
    return 0;
}

我在 GCC4.3.2 中的测试服

4

2 回答 2

1

这可能是 VS2013 中的一个错误。但是,该错误似乎已在 VS14 CTP 中修复,您的代码编译时没有错误。

于 2014-09-18T07:27:53.917 回答
0

可悲的是,这甚至不是错误的行为。由于 MS 的编译器不是最快的,而且它也不是对标准的解释,它们几乎从不接近它。

即 MSVC2013 普通 C 编译器是 c89 和 c99 子句的混合,还有许多额外的例外,因为不支持标准所说的 ac 编译器必须支持的东西,并且还具有标准所说的 ac 编译器不允许拥有的许多功能。

因此,在使用 Microsoft Visual C 编译器编译 ac 或 c++ 应用程序时,不要依赖标准。

(这可能就是为什么他们称它为 Visual C,因为他们甚至不允许称它为普通 C ;))

于 2014-09-18T07:34:08.163 回答