Попытка соединить список мест, что делает пример неопределенным поведением.
#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;
...
}
Я проверю строки вплоть до той, где вы создаете экземпляр вектора с вашим типом A
. Стандарт должен сказать
В 23.1/3
:
Тип объектов, хранящихся в этих компонентах, должен соответствовать требованиям типов CopyConstructible (20.1.3) и дополнительным требованиям назначаемых типов.
В 23.1/4
(выделено мое):
В таблице 64 T - это тип, используемый для создания экземпляра контейнера, t - это значение T, а u - это значение ( возможно const ) T.
+-----------+---------------+---------------------+
|expression |return type |postcondition |
+-----------+---------------+---------------------+
|t = u |T& |t is equivalent to u |
+-----------+---------------+---------------------+
Таблица 64
В 12.8/10
:
Если определение класса явно не объявляет оператор присваивания копии, он объявляется неявно. Неявно объявленный оператор присваивания копии для класса X будет иметь вид
X& X::operator=(const X&)
если
- каждый прямой базовый класс B из X имеет оператор присваивания копии, параметр которого имеет тип const B &,
const volatile B & or B и
- для всех нестатических членов-данных X, которые имеют тип класса M (или его массив), каждый такой тип класса имеет оператор присваивания копии, параметр которого имеет тип const M &, const volatile M & or M.
В противном случае неявно объявленный оператор присваивания копии будет иметь вид
X& X::operator=(X&)
(обратите внимание на последнее и второе последнее предложение)
В 17.4.3.6/1 and /2
:
В некоторых случаях (функции замены, функции-обработчики, операции над типами, используемые для создания экземпляров стандартных шаблонных компонентов библиотеки), стандартная библиотека C ++ зависит от компонентов, предоставляемых программой C ++. Если эти компоненты не соответствуют их требованиям, Стандарт не устанавливает требований к реализации.
В частности, эффекты не определены в следующих случаях:
- для типов, используемых в качестве аргументов шаблона при создании экземпляра компонента шаблона, если операции над типом не реализуют семантику применимого подпункта Требования (20.1.5, 23.1, 24.1, 26.1). Операции с такими типами могут сообщать об ошибке, вызывая исключение, если не указано иное.
Теперь, если вы посмотрите на спецификацию auto_ptr
, вы заметите, что у нее есть оператор присваивания копии, который принимает неконстантный auto_ptr
. Таким образом, неявно объявленный оператор присваивания копии вашего класса также примет неконстантный тип в качестве параметра. Если вы внимательно прочитаете вышеприведенные места, вы увидите, как это говорит о том, что создание вектора с вашим типом, как написано, является неопределенным поведением.