Где стандартные правила, которые могут интерпретировать проблему неправильной проверки в `std::shared_ptr`C++

Программы на C++. Форум разработчиков
Anonymous
 Где стандартные правила, которые могут интерпретировать проблему неправильной проверки в `std::shared_ptr`

Сообщение Anonymous »

Рассмотрим этот пример:
a.h

Код: Выделить всё

#pragma once
#include 

struct AAA;
std::shared_ptr createAAA();

a.cpp

Код: Выделить всё

#include "A.h"
struct AAA : public std::enable_shared_from_this{};
void destory_AAA(AAA* v) {
v->~AAA();
}
std::shared_ptr createAAA() {
auto ret = std::make_shared();
// check if shared_from_this is OK after make_shared
auto shared_from_ths = ret->shared_from_this();  // #1
return shared_from_ths;
}
main.cpp

Код: Выделить всё

#include "A.h"
void destory_AAA(AAA* v);
std::shared_ptr unused_func(AAA* ptr) {
return std::shared_ptr{ ptr, destory_AAA };  // #2
}
int main()
{
createAAA();
}
В этом примере в режиме отладки определенного MSVC #1 выдает ошибку bad слабый_ptr. Некоторые ребята говорят, что эта проблема возникает из-за правила ODR [basic.def.odr] p15. Однако я думаю, что определение шаблона std::shared_ptr не нарушает эти правила.
Какое правило в стандарте C++ интерпретирует причину проблемы? Я подозреваю, что это правило [temp.res.general] p6:

Достоверность шаблонного объекта может быть проверена до любого создания экземпляра. Программа некорректна, диагностика не требуется, если:
  • [...]
  • интерпретация такой конструкции в гипотетической реализации отличается от интерпретации соответствующей конструкции в любой реальной реализации шаблонной сущности.

Оба #1 и #2 приведут к созданию экземпляра следующей шаблонной функции

Код: Выделить всё

    template 
void _Set_ptr_rep_and_enable_shared(_Ux* const _Px, _Ref_count_base* const _Rx) noexcept { // take ownership of _Px
this->_Ptr = _Px;
this->_Rep = _Rx;
if constexpr (conjunction_v) {
if (_Px && _Px->_Wptr.expired()) {
_Px->_Wptr = shared_ptr(*this, const_cast(_Px));
}
}
}
Однако в TU main.cpp структура AAA является неполной, тогда как в a.cpp она завершена. Это правильное правило, интерпретирующее проблему? Уместно ли здесь правило ODR?


Подробнее здесь: https://stackoverflow.com/questions/790 ... g-check-in

Вернуться в «C++»