我正在尝试更新一些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,他们将做得比您最有可能的工作更好。如果您不能直接使用它们,请阅读他们所做的工作,然后自己重新实现。