C std:.auto_ptr或std :: suolide_ptr(支持多个编译器,甚至旧的C 03编译器
C++ std:.auto_ptr or std::unique_ptr (to support multiple compilers, even old C++03 compilers)?
我正在尝试更新一些C 代码,我想转向更现代的代码(C 11),但是我仍然需要使用一些较旧的代码来编译代码编译器(C 03符合),由于受支持的平台约束。
我知道在C 11编译器std :: auto_ptr已弃用,但是由于较旧的编译器支持,我不能只是用std :: simolor_ptr。
替换它们是否有一个很好的做法来处理此"旧编译器支持,但开始转到C 11"?
如您所述,std :: auto_ptr<>在C 11中已弃用(参考)。
移至C 11 std :: suolide_ptr<>是正确的方式,正如Herb Sutter所指出的gotw89:
- 与auto_ptr有什么关系?
Auto_ptr最慈善地描述为在C 具有移动语义之前创建唯一_ptr的英勇尝试。Auto_ptr现在已弃用,不应在新代码中使用。
如果您在现有代码库中具有auto_ptr,则有机会尝试将auto_ptr的全局搜索和重新安置到unique_ptr;绝大多数用途都可以正常工作,它可能会暴露(作为编译时间错误)或(默默地修复)一个或两个您不知道的错误。
还请注意,C 17将删除std :: auto_ptr。
我认为解决您的问题可能有不同的方法,"正确"一个也取决于您的实际代码的编写。
一些选择是:
选项1
使用boost :: unique_ptr
选项2
有条件地使用基于__cplusplus的auto_ptr或unique_ptr。
类myclass {
#if __cplusplus<201103L
std :: auto_ptr m_ptr;
#else
std :: unique_ptr m_ptr;
#endif
...
这将散布在您引用auto_ptr的每个地方,我真的不喜欢它。
如果您对std :: auto_ptr的所有引用已经键入(只要有条件地更改typedef)。
选项3
有条件地使用并将其混音到"定义"auto_ptr(并在没有std ::名称空间的情况下引用它)。
#if __cplusplus<201103L
使用std :: auto_ptr;
#else
模板
使用auto_ptr = std :: unique_ptr;
#endif
缺点:您一直使用" auto_ptr",但是在C 11中,这意味着std :: simelor_ptr。
真的很困惑...
选项3.1
可能比选项2好一点:
反向使用别名,更喜欢unique_ptr名称。
选项4
将STD ::智能指针(有条件地auto_ptr或unique_ptr)在您自己定义的模板中智能指针类。
这可能很麻烦,需要在您的新课程中搜索和更换所有auto_ptr。
其他肮脏的选项
其他选项涉及std ::名称空间内的定义,我认为标准禁止,
或使用预处理器#Define进行... ehm ...unique_ptr到auto_ptr仅适用于旧的C 03编译器。
在这种确切情况下,您可以使用boost::unique_ptr
而不是auto_ptr
开始对代码进行现代化,不推荐。
总的来说,C 11库的大部分是直接从Boost拿来的,因此它将是开始的好地方。
如果我很认真,我会创建一个notstd
名称空间。
目标是在C 11中,notstd
由std
类型的一系列别名组成。在C 03中,它具有伪C 11代码。
C 03 notstd
代码与C 11 std
不兼容,而是有效的C 03 notstd
又会产生有效的C 11行为。
例如,我可能会使用特殊标记的"参考 - wrapper"类型用于notstd::move
参考而不是RVALUE参考,并且让我的仅移动类型需要此类标记的"参考 - wrapper"s。
namespace notstd {
template<class U>
struct moved_t {
U& u;
// relies on NRVO, which is pretty universally supported.
// also relies in U being default-constructible:
operator U()const{ U tmp; std::swap(u, tmp); return tmp; }
};
template<class U>
moved_t<U> move(U& u) { return {u}; }
template<class T>
struct unique_ptr {
unique_ptr( moved_t<unique_ptr<T>> > ); // move ctor
template<class U>
unique_ptr( moved_t<unique_ptr<U>> > ); // move ctor
private:
unique_ptr(unique_ptr const&);
};
}
,您的代码将使用notstd::unique_ptr<T>
。不会有隐式的rvalue转换,因此每个移动notstd::unique_ptr<T>
的位置都必须notstd::move
。
可悲的是,这意味着notstd::unique_ptr<T>
不能放入std
容器中。可能必须进行一些黑客攻击才能使其工作(auto_ptr
也不能安全)。
这是一项非平凡的任务。boost::unique_ptr
试图在C 03中生成唯一的_ptr,他们将做得比您最有可能的工作更好。如果您不能直接使用它们,请阅读他们所做的工作,然后自己重新实现。
- C/C++编译器通常会删除重复的库吗
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- Win32编译器选项和内存分配
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++,我收到一个无法理解的编译器错误
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 我需要知道编译器如何在cpp中使用析构函数
- 编译器如何区分std::vector的构造函数
- CLANG 编译器 说:变量"PTR"可能未初始化
- 告诉c++编译器该参数没有别名
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么所有C++编译器都会崩溃或挂起此代码
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 视觉 C++编译器在计算其参数之前是否允许将函数 ptr 存储在寄存器中?