C++ &引用;“后移植”;空ptr到C++-C&x2B之前+;0x程序

C++ &引用;“后移植”;空ptr到C++-C&x2B之前+;0x程序,c++,c++03,nullptr,backport,forward-compatibility,C++,C++03,Nullptr,Backport,Forward Compatibility,或多或少是标题所暗示的。虽然我很抱歉,但我想为它的发生做好准备,我还想减少我为了使用它的一些功能而必须重写的代码量。这样我就可以一次获得前后兼容性 我发现其中一个最有趣的是,我最近经常使用它 在检查了“官方解决方案”之后,我决定在C++和未来C++ 0x程序中使用这个。第二部分很简单——作为一个关键字,nullptr将得到简单的支持。但第一部分让我有些不舒服 迈尔斯提案的作用如下: class nullptr_t { // ← this is my issue // definition

或多或少是标题所暗示的。虽然我很抱歉,但我想为它的发生做好准备,我还想减少我为了使用它的一些功能而必须重写的代码量。这样我就可以一次获得前后兼容性

我发现其中一个最有趣的是,我最近经常使用它

在检查了“官方解决方案”之后,我决定在C++和未来C++ 0x程序中使用这个。第二部分很简单——作为一个关键字,
nullptr
将得到简单的支持。但第一部分让我有些不舒服

迈尔斯提案的作用如下:

class nullptr_t { // ← this is my issue
    // definition of nullptr_t
} nullptr = { };
该方案的问题在于,它按照C++0x的要求将要声明的类型声明为
std::nullptr\t
。这意味着要使解决方案“感觉是本地的”,必须通过重新打开
std::
名称空间来添加类型<强>我有一个理解,在C++程序中是非法的(与添加明显的FROWN-GET-GO-A警告的特殊性不同)。p>

我想在C++程序中使用一个舒适的<强>和>强>合法的方式使用<代码> null pTr>代码>。我想到的一个选项是在另一个名称空间中声明类型,然后使用

将其引入:

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?
这是正确的方法吗?它将强制
使用
指令,这也强制执行特定的
#include
指令顺序。我认为C++0x之前的代码不会请求带有名称空间的类型
nullptr\t
(例如,作为函数参数类型)是正确的吗?如果这样做的话,它真的能让人“感觉自己是本地人”吗



作为补充,尝试或将一些优秀的C++ 0x东西移植到C++中以获得更好的兼容性和编码,是一种欢迎还是不赞成?同时,我集成了此解决方案和我正在研究的其他解决方案。

除非您能想出需要声明另一个类型为
nullptr\t
的对象的原因(我不能),否则我会将该类型隐藏起来,并将
nullptr
放在全局命名空间中,以尽可能接近地模拟关键字:

namespace mylibrary
{
    class nullptr_t
    {
        ....
    };
}

mylibrary::nullptr_t nullptr = { };

不允许将内容添加到
命名空间std
的主要原因是,这样就不会把已经存在的内容搞砸。否则这很容易做到。我在过去发现,对于使用内置类型(如
std::vector
)实例化的容器,输出运算符有多个定义。但是,
nullptr\t
未在此命名空间中定义,添加
typedef
应该是无害的。也就是说,我将在与
名称空间std
不同的名称空间中定义
nullptr\u t
,然后为
nullptr\u t
添加
typedef
。变量
nullptr
无论如何都需要在全局范围内声明,因为它在C++2011中使用时是非限定的


是否需要类型
std::nullptr\u t
,取决于您是否有兴趣使用此类型添加签名。例如,
std::shared_ptr
可以与
nullptr
进行比较。为此,有必要添加适当的重载,其中提到类型
std::nullptr\u t
(或使用此类型的其他名称)。

是的,隐藏类型是我想要做的。我多多少少关心的是,是否有任何原因导致某人需要使用类型
nullptr\t
来处理任何不能通过简单地传递
nullptr
或指针类型来完成的事情。我一直认为不能向
namespace std
添加内容的原因不是为了不让您弄乱那里的东西,但是,这样您的代码将在许多编译器上编译(可能使用您选择的名称),因此当标准向
std
名称空间添加内容时,它将继续编译。(1)我相信名称空间是为实现保留的,因此,
可以在
std
中执行它想要的任何操作。(2) 这样,如果我的代码只使用一个标准库进行编译,那么它就可以使用标准库的所有其他一致性实现进行编译。(3) 所有以
\u t
结尾的名称都是为C++03中的实现保留的。据我所知,“下划线”规则的存在正是为了“实现”可以自由地使用这些名称(只需检查
的任何副本,超出标准提供的名称(例如
cin
cout
)即使在namespace std中也没有保留任何其他名称;在这一点上,
typedef
不会像实际声明那样损害前向兼容性,除非它可以防止我们添加太多内容(如“详细名称空间”)。啊,我有点不同意。从"一些额外的标识符名称类是为C语言或POSIX.1环境的未来扩展保留的。虽然现在将这些名称用于您自己的目的可能不会导致问题,但它们确实会增加与C或POSIX标准的未来版本冲突的可能性,因此您应该避免使用这些名称带有“_t”的nd是保留的“@DietmarKühl:我检查过了,C++11没有保留它们,只是POSIX。