6

我想让我的代码在旧版 C++(使用“NULL”的 C++ 代码)和新的 C++11 标准(使用“nullptr”的 C++ 代码)上都可编译

我正在使用 GCC,但计划在完成最重要的事情时也为 VS 重新编译整个代码库。

我是否应该期望 GCC 和 VS 都会做类似的事情

#define NULL nullptr

还是我自己做更好(当然使用不同的名称,其中 MY_LIB 将被我的库后缀替换)?

#ifndef nullptr
    #define MY_LIB_NULL NULL
#else
    #define MY_LIB_NULL nullptr
#endif

我想要实现的是无论是否实现了 C++11 功能都可以编译的代码(而且由于我没有使用模板,所以它们很少)。

例如,关键字“override”和“final”已经完成。

MY_LIB_OVERRIDE //macro, defines to "override" if c++11 is present.
MY_LIB_FINAL    //macro, defines to "final" if c++11 is present.

我问这个问题是因为我知道“nullptr”问题有点奇怪,所以也许只是做我已经为覆盖和最终所做的同样的事情,是错误的。需要对此发表意见。欢迎任何帮助。

4

3 回答 3

4

您可能可以通过以下方式创建my_nullptr类型的“假”:my_nullptr_t

const class my_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;
        }

        /* Safe boolean conversion */
        operator void*() const
        {
            return 0;
        }

    private:

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

} my_nullptr = {};

这适用于 C++03 和 C++11,并且应该始终是安全的,无论实现了哪个 C++11 功能。该解决方案实际上已经在本主题中讨论过,该主题提出了nullptr_t基于官方提案的版本。

于 2012-12-03T15:26:38.000 回答
1

NULL是一个扩展为空指针常量的宏。它仍然像以前一样工作。必须与非 C++11 编译器一起使用的代码应使用NULL.

于 2012-12-03T14:23:33.270 回答
0

我认为以下将起作用:

#include <cstddef>

#ifndef MY_LIB_NULL
    #ifndef NULL //check for NULL
        #define MY_LIB_NULL nullptr
    #else
        #define MY_LIB_NULL NULL ///use NULL if present
    #endif
#endif

基本上我检查“NULL”。wich 是一个宏并且可以检查,直到编译器附带该宏(可能是),而不是使用宏有效,当编译器将仅提供“nullptr”并且不再具有 NULL 时使用 nullptr(可能在一个遥远的未来,但似乎我们可以愉快地继续使用 NULL!)

我认为这比重新定义“nullptr”更安全(就像大多数人试图做的那样)

于 2012-12-03T08:44:56.477 回答