Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类,该类包含存储在vector中的auto_ptr_C++_Stl - Fatal编程技术网

C++ 类,该类包含存储在vector中的auto_ptr

C++ 类,该类包含存储在vector中的auto_ptr,c++,stl,C++,Stl,在对我的回答中,我指出,如果类具有用户定义的复制构造函数,则包含auto_ptr的类可以存储在向量中 有几条评论认为情况并非如此,因此这个问题旨在澄清问题。考虑下面的代码: #include <memory> #include <vector> using namespace std; struct Z {}; struct A { A( Z z ) : p( new Z(z) ) {} A( const A & a )

在对我的回答中,我指出,如果类具有用户定义的复制构造函数,则包含auto_ptr的类可以存储在向量

有几条评论认为情况并非如此,因此这个问题旨在澄清问题。考虑下面的代码:

#include <memory>
#include <vector>
using namespace std;

struct Z {};

struct A {

    A( Z z ) 
        : p( new Z(z) ) {} 

    A( const A & a ) 
        : p( a.p.get() ? new Z( *a.p.get()) : 0 ) {}

    // no assigment op or dtor defined by intent

    auto_ptr <Z> p;
};

int main() {
    vector <A> av;              
    Z z;                    
    A a(z);
    av.push_back( a );      
    av.push_back( A(z) );   
    av.clear();             
}                           
#包括
#包括
使用名称空间std;
结构Z{};
结构A{
A(Z)
:p(新Z(Z)){}
A(常数A&A)
:p(a.p.get()?新Z(*a.p.get()):0){
//没有意图定义的分配op或dtor
自动ptr p;
};
int main(){
向量av;
Z Z;
A(z);
av.推回(a);
平均推回(A(z));
av.clear();
}                           
请检查以上内容&在您的回复中指出未定义的位置 C++标准的含义可以在这个特定的方式中使用。我不关心这个类是否有用、行为良好、可排序,也不关心它在异常情况下如何执行

请注意,这不是一个关于创建自动PTR向量的有效性的问题-我很清楚与此相关的问题。

感谢大家对本项目的投入 回顾可能是一个相当愚蠢的问题 问题。我想我太专注了 在副本上&忘记了 分配幸运的获胜者 验收点(和平均值) 奖品!)是一种典型的 详尽的解释(对不起 (耳塞)


由于常规的
auto_ptr
语义可能表明所有权在复制过程中传递,因此我宁愿在这里使用
boost::scoped_ptr
。当然,赋值运算符丢失了。

我认为上面的代码不一定会编译。当然,
std::vector
的实现者可以自由地要求从
const A&
提供赋值运算符

并且刚刚尝试过,它没有在VisualStudioC++ 2008 Service PACK 1上编译:

二进制“=”:未找到 接受类型为的右侧操作数 “常数A”(或不可接受) 转换)

我的猜测是,在Herb Sutter的指导下,VC++中的容器类尽一切努力将标准要求强加给它们的类型参数,特别是使它们难以使用
auto_ptr
。当然,他们可能已经超越了标准所规定的界限,但我似乎记得它要求真正的任务以及真正的副本构建


但是,它确实是在g++3.4.5中编译的。

下面是什么

cout << av[ 0 ] << endl;

cout存储在容器中的对象要求是“可复制的”和“可分配的”(C++2008 23.1/3)

您的类尝试处理CopyConstructable需求(尽管我认为它仍然不满足它-我编辑了该参数,因为它不是必需的,并且我认为它是可论证的),但它不处理可分配的需求。要可赋值(C++2008 23.1/4),以下内容必须为真,其中
t
t
的值,
u
是(可能
const
t

t=u
返回一个
t&
t
相当于
u

该标准还在注释(20.4.5/3)中指出:“
auto_ptr
不满足标准库容器元素的可复制和可分配要求,因此使用
auto_ptr
实例化标准库容器会导致未定义的行为。”


由于您没有声明或定义赋值运算符,因此将提供一个使用
auto_ptr
赋值运算符的隐式赋值运算符,这肯定会使
t
不等同于
u
,更不用说它对“
const t u
”值根本不起作用(这就是我所指出的——我只是指出标准的确切部分)。

试图将使示例行为未定义的位置列表放在一起

#include <memory>
#include <vector>
using namespace std;

struct Z {};

struct A {

    A( Z z ) 
        : p( new Z(z) ) {} 

    A( const A & a ) 
        : p( a.p.get() ? new Z( *a.p.get()) : 0 ) {}

    // no assigment op or dtor defined by intent

    auto_ptr <Z> p;
};

int main() {
    vector <A> av;  
    ...
}
表64

12.8/10
中:

如果类定义没有显式声明复制赋值运算符,则隐式声明一个。类X的隐式声明复制赋值运算符的形式为

X& X::operator=(const X&)
X& X::operator=(X&)
如果

  • X的每个直接基类B都有一个复制赋值运算符,其参数类型为const B&, 常量挥发性食宿,以及
  • 对于类类型为M(或其数组)的X的所有非静态数据成员,每个此类类类型都有一个复制赋值运算符,其参数类型为const M&,const volatile M&或M
否则,隐式声明的复制赋值运算符将具有

X& X::operator=(const X&)
X& X::operator=(X&)
(注意最后一句和第二句)

17.4.3.6/1和/2中

在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件。如果这些组件不符合它们的要求,则标准不要求实现。

特别是,在以下情况下,影响未定义:

  • 对于实例化模板组件时用作模板参数的类型,如果该类型上的操作未实现适用需求子类(20.1.5、23.1、24.1、26.1)的语义。除非另有规定,否则此类类型上的操作可以通过引发异常来报告失败
现在,如果您查看
auto_ptr
的规范,您会注意到它有一个复制赋值操作符,它接受一个非常量
auto_ptr