我了解到STL可以禁止程序员将auto_ptr放入容器中.例如,以下代码无法编译:
auto_ptr<int> a(new int(10));
vector<auto_ptr<int> > v;
v.push_back(a);
Run Code Online (Sandbox Code Playgroud)
auto_ptr有复制构造函数,为什么这段代码甚至可以编译?
Lig*_*ica 11
namespace std {
template <class Y> struct auto_ptr_ref {};
template <class X>
class auto_ptr {
public:
typedef X element_type;
// 20.4.5.1 construct/copy/destroy:
explicit auto_ptr(X* p =0) throw();
auto_ptr(auto_ptr&) throw();
template <class Y> auto_ptr(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr&) throw();
template <class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
auto_ptr& operator=(auto_ptr_ref<X>) throw();
~auto_ptr() throw();
// 20.4.5.2 members:
X& operator*() const throw();
X* operator->() const throw();
X* get() const throw();
X* release() throw();
void reset(X* p =0) throw();
// 20.4.5.3 conversions:
auto_ptr(auto_ptr_ref<X>) throw();
template <class Y> operator auto_ptr_ref<Y>() throw();
template <class Y> operator auto_ptr<Y>() throw();
};
}
Run Code Online (Sandbox Code Playgroud)
虽然有一个复制构造函数,但它需要引用非const
.临时工具可能不会与此绑定,因此在任何使用临时工位的地方都有效禁止该类型的容器内部工作; 另外,push_back
接受一个引用const
,所以由于const
正确性,新的内部元素不可能通过复制构造push_back
的参数.
(该维基百科页面说"由于其复制语义,auto_ptr可能不会在可能在其操作中执行元素副本的STL容器中使用";这并不意味着容器会神奇地检查复制构造函数中的代码以决定是否想要使类型作为元素类型工作.相反,它只是函数签名.)
无论如何,std::auto_ptr
从C++ 11开始被弃用,因为在一些人看来,这std::auto_ptr
是愚蠢的.对不起,std::auto_ptr
.
关于编译器如何检测这种情况(或者STL如何在那里导致错误)的特定问题,您应该读取编译器的确切输出,它将包含一堆错误,这些错误将导致无法执行转换从const X
到X
它丢弃const限定符,其中X
可以是std::auto_ptr<>
直接或其他内部细节类型.
特别是,std::vector::push_back
接受参数const &
,并在内部尝试使用可用的复制构造函数复制构造动态数组内的元素,在std::auto_ptr
需要非const引用的情况下.有些东西:
void push_back( std::auto_ptr<int> const & x ) {
// ensure enough capacity if needed...
new (buffer + size()) std::auto_ptr<int>( x ); // !!! cannot bind x to non-const&
// complete the operation (adjust end pointer, and such)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1909 次 |
最近记录: |