У меня есть std::shared_ptr
с пользовательским делетером, и в этом деле я хотел бы взять временную копию оригинала std::shared_ptr
. Выражается в виде кода:
struct Foo : public std::enable_shared_from_this<Foo>
{};
void deleter(Foo *f)
{
{
std::shared_ptr<Foo> tmp = f->shared_from_this(); // Line A
}
delete f;
}
int main()
{
std::shared_ptr<Foo> foo(new Foo, &deleter);
}
Мой вопрос: на линии А, можно ли что-нибудь сказать о вызове shared_from_this()
? Это законно? Если да, то стандарт говорит что-либо о его возвращаемом значении? Если мы заменим enable_shared_from_this
на другую weak_ptr
или глобальную ссылку на foo
, ответ будет таким же?
Clang с libС++ и gcc с libstdС++ оба производят код, который заканчивается на исключении bad_weak_ptr
, но я не могу проследить его, как того требует стандарт. Является ли это конкретной реализацией, или я пропустил правило?
Все соответствующие правила, которые я нашел (цитируя С++ 11):
20.7.2.2.2
shared_ptr
деструктор1... если
*this
принадлежит объектp
, а deleterd
,d(p)
вызывается 2 [Примечание:... Поскольку уничтожение*this
уменьшает количество экземпляров, которые разделяют право собственности на*this
одним, после того, как*this
был уничтожен все экземплярыshared_ptr
, которые разделяют право собственности на*this
, будут сообщите ause_count()
, что на один меньше его предыдущего значения. -end note]20.7.2.2.5
shared_ptr
наблюдатели7
use_count
Возвращает: количество объектовshared_ptr
,*this
включено, которые разделяют право собственности на*this
, или 0 когда*this
пусто.
Мне кажется, что неясно, происходит ли декремент use_count
до или после вызова делетера. Получает bad_weak_ptr
надежный результат, или это просто неуказано?
Обратите внимание, что я намеренно избегаю ситуации, когда указатель типа tmp
в моем примере кода переживет выполнение удаления.