Правда ли, что объявление unique_ptr, в отличие от объявления auto_ptr, четко определено, когда его тип шаблона имеет неполный тип?
я написалЭта статья и получил несколько комментариев, которые смутили меня.
Это в основном сводится к тому, что я виделT2
использовался только в качестве параметра шаблона и по ошибке сделал вывод, что поэтому я могу воспользоваться возможностью предварительного объявления:
struct T2;
struct T1
{
std::auto_ptr<T2> obj;
};
Это вызывает UB, если я не буду определятьT2
где-то в том же ту, потому чтоstd::auto_ptr<T2>
звонкиdelete
на его внутреннейT2*
, а такжепризваниеdelete
on an pointer to an object of an incomplete type whose complete type has a non-trivial destructor is undefined:
[C++11: 5.3.5/5]:
If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.
Набор инструментов GCC, который я использовал & # x2014; v4.3.3 (Sourcery G ++ Lite 2009q1-203) & # x2014; был достаточно любезен, чтобы сообщить мне с запиской:
note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
хотя, кажется, трудно получить эту диагностику в других версиях GCC.
Я чувствовал, что было бы намного легче обнаружить ошибку, как это, еслиdelete
указатель на экземпляр неполного типа былill-formed а не UB, но это похоже на проблему, которую можно решить для реализации, поэтому я понимаю, почему это UB.
Но тогда мне сказали, что если бы я использовалstd::unique_ptr<T2>
вместо этого это будет безопасно и послушно.
N3035 якобы говорит в 20.9.10.2:
The template parameter T
of unique_ptr
may be an incomplete type.
Все, что я могу найти в C ++ 11, это:
[C++11: 20.7.1.1.1]:
/1 The class template default_delete
serves as the default deleter (destruction policy) for the class template unique_ptr
.
/2 The template parameter T
of default_delete
may be an incomplete type.
Но,default_delete
& APOS; soperator()
требует полного типа:
[C++11: 20.7.1.1.2/4]:
If T
is an incomplete type, the program is ill-formed.
Я полагаю, мой вопрос заключается в следующем:
Are the commenters on my article correct in saying that a translation unit consisting of only the following code is well-formed and well-defined? Or are they wrong?
struct T2;
struct T1
{
std::unique_ptr<T2> obj;
};
If they are correct, how is a compiler expected to implement this, given that there are good reasons for it being UB, at least when an std::auto_ptr
is used?