"using"(或其他机制)在 C++11 中将 unique_ptr 换成 auto_ptr?
"using" (or other mechanism) to swap in unique_ptr for auto_ptr in C++11?
我在 Cygwin 下使用 -std=c++11
:
捕获编译警告
cryptlib.cpp: In member function ‘virtual size_t PK_Signer::SignMessage(RandomNumberGenerator&, const byte*, size_t, byte*) const’:
cryptlib.cpp:770:41: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
^
我尝试添加:
#if defined(MYLIB_CXX11)
using auto_ptr = std::unique_ptr;
#else
using std::auto_ptr;
#endif
auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
但结果如下,即使包含 <memory>
。
$ make cryptlib.o
c++ -std=c++11 -DNDEBUG -g2 -O3 -fPIC -march=native -DCRYPTOPP_DISABLE_ASM -Wall -Wextra -pipe -c cryptlib.cpp
cryptlib.cpp:770:27: error: no type named 'unique_ptr' in namespace 'std'
using auto_ptr = std::unique_ptr;
~~~~~^
我还尝试了以下变体:
#if defined(MYLIB_CXX11)
typedef std::unique_ptr<T> local_ptr<T>;
#else
typedef std::auto_ptr local_ptr;
#endif
我无法完全切换到 unique_ptr
,因为它是一个 C++03 库,而 C++03 缺少 unique_ptr
。而且我不能让脏编译在 C++11 下继续,因为干净编译是一个安全门,治理不会让库通过。 (并且警告技巧是不可能的,因为这应该是简单的、容易实现的。警告技巧包括禁用警告)。
是否可以使用“using
”换入unique_ptr
?还是有其他机制?
你有两个选择。
在您的应用程序中使用 auto_ptr
,并让库保持原样。弃用警告不会阻止应用程序正常工作,它们只是提供帮助。
在您的应用程序中使用 unique_ptr
,并修改库以也使用 unique_ptr
。
你不能把它们混在一起。如果您不能修改库,那么您将被迫在代码中使用 auto_ptr
。
了解代码在您的控制之下并且可以在有或没有 C++11 支持的情况下重新编译,可以为所需的智能指针创建别名(std::unique_ptr
或 std::auto_ptr
).
template <typename T>
struct local_ptr {
#if defined(MYLIB_CXX11)
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
然后在客户端代码中使用;
local_ptr< PK_MessageAccumulator>::ptr managed = //...
语法比预期的更笨拙,但这是为了满足支持 C++03 的要求。
在所有情况下,长期的解决方案是排除使用 auto_ptr
或消除已弃用的警告。
我尝试添加:
using auto_ptr = std::unique_ptr;
using std::auto_ptr;
auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
但结果如下,即使包含在内。
cryptlib.cpp:770:27: error: no type named 'unique_ptr' in namespace 'std'
那是因为 std::unique_ptr
是一个 template
,而不是一个类型。相反,这应该有效
#if __cplusplus >= 201103L
// with C++11 we have std::unique_ptr (and std::auto_ptr is deprecated)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
// assuming C++03 when there is std::auto_ptr
using std::auto_ptr;
#endif
(要求您在代码中仅使用 auto_ptr
,而不是 std::auto_ptr
)。
当然,我假设您使用有效的 C++ 编译器和标准库。在MacOS上可以使用(可能需要安装Xcode和命令行工具)
/usr/bin/c++ -std=c++11 -stdlib=libc++
调用 clang C++ 编译器和 clang C++ 标准库。
我在 Cygwin 下使用 -std=c++11
:
cryptlib.cpp: In member function ‘virtual size_t PK_Signer::SignMessage(RandomNumberGenerator&, const byte*, size_t, byte*) const’:
cryptlib.cpp:770:41: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
^
我尝试添加:
#if defined(MYLIB_CXX11)
using auto_ptr = std::unique_ptr;
#else
using std::auto_ptr;
#endif
auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
但结果如下,即使包含 <memory>
。
$ make cryptlib.o
c++ -std=c++11 -DNDEBUG -g2 -O3 -fPIC -march=native -DCRYPTOPP_DISABLE_ASM -Wall -Wextra -pipe -c cryptlib.cpp
cryptlib.cpp:770:27: error: no type named 'unique_ptr' in namespace 'std'
using auto_ptr = std::unique_ptr;
~~~~~^
我还尝试了以下变体:
#if defined(MYLIB_CXX11)
typedef std::unique_ptr<T> local_ptr<T>;
#else
typedef std::auto_ptr local_ptr;
#endif
我无法完全切换到 unique_ptr
,因为它是一个 C++03 库,而 C++03 缺少 unique_ptr
。而且我不能让脏编译在 C++11 下继续,因为干净编译是一个安全门,治理不会让库通过。 (并且警告技巧是不可能的,因为这应该是简单的、容易实现的。警告技巧包括禁用警告)。
是否可以使用“using
”换入unique_ptr
?还是有其他机制?
你有两个选择。
在您的应用程序中使用
auto_ptr
,并让库保持原样。弃用警告不会阻止应用程序正常工作,它们只是提供帮助。在您的应用程序中使用
unique_ptr
,并修改库以也使用unique_ptr
。
你不能把它们混在一起。如果您不能修改库,那么您将被迫在代码中使用 auto_ptr
。
了解代码在您的控制之下并且可以在有或没有 C++11 支持的情况下重新编译,可以为所需的智能指针创建别名(std::unique_ptr
或 std::auto_ptr
).
template <typename T>
struct local_ptr {
#if defined(MYLIB_CXX11)
typedef std::unique_ptr<T> ptr;
#else
typedef std::auto_ptr<T> ptr;
#endif
};
然后在客户端代码中使用;
local_ptr< PK_MessageAccumulator>::ptr managed = //...
语法比预期的更笨拙,但这是为了满足支持 C++03 的要求。
在所有情况下,长期的解决方案是排除使用 auto_ptr
或消除已弃用的警告。
我尝试添加:
using auto_ptr = std::unique_ptr;
using std::auto_ptr;
auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
但结果如下,即使包含在内。
cryptlib.cpp:770:27: error: no type named 'unique_ptr' in namespace 'std'
那是因为 std::unique_ptr
是一个 template
,而不是一个类型。相反,这应该有效
#if __cplusplus >= 201103L
// with C++11 we have std::unique_ptr (and std::auto_ptr is deprecated)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
// assuming C++03 when there is std::auto_ptr
using std::auto_ptr;
#endif
(要求您在代码中仅使用 auto_ptr
,而不是 std::auto_ptr
)。
当然,我假设您使用有效的 C++ 编译器和标准库。在MacOS上可以使用(可能需要安装Xcode和命令行工具)
/usr/bin/c++ -std=c++11 -stdlib=libc++
调用 clang C++ 编译器和 clang C++ 标准库。