static_pointer_cast для weak_ptr

В c++0x есть std::static_pointer_cast для std::shared_ptr, но нет эквивалентного метода для std::weak_ptr. Это намеренно или недосмотр? Если недосмотр, как бы я определил соответствующую функцию?


person tgoodhart    schedule 19.05.2011    source источник


Ответы (3)


Это должно сделать это за вас:

template<class T, class U>
std::weak_ptr<T>
static_pointer_cast(std::weak_ptr<U> const& r)
{
    return std::static_pointer_cast<T>(std::shared_ptr<U>(r));
}

Это вызовет исключение, если срок действия weak_ptr истек. Если вы хотите получить null weak_ptr, используйте вместо него r.lock().

person Howard Hinnant    schedule 19.05.2011
comment
Вы вообще в курсе этой истории? Учитывая, насколько банально это было написать, мне интересно, почему комитет по стандартам не включил это. - person tgoodhart; 20.05.2011
comment
Я только что просмотрел документы стандартов, и мне кажется, что никто никогда этого не предлагал. Я также не могу найти запись о том, что его запрашивали или предлагали для повышения (исходный источник std::weak_ptr). Возможно, причина в том, что это тривиально написать и нетривиально выбрать правильную политику (throw или null). И предоставление двух функций (по одной для каждой политики) неоптимально, потому что static_pointer_cast должно быть универсальным именем, которое можно использовать в коде, где тип указателя является универсальным. - person Howard Hinnant; 20.05.2011

Версия Ховарда верна, но во многих случаях имеет смысл просто передать weakptr.lock() в качестве параметра в std::static_pointer_cast:

std::weak_ptr<A> a = ...;  
std::weak_ptr<B> b = std::static_pointer_cast<B>(a.lock());

Этот синтаксис явно показывает, что происходит, и упрощает чтение кода.

person Alex    schedule 23.10.2014
comment
Кажется, здесь есть ошибка. Поскольку a.lock() является временным, базовый указатель может быть удален, в то время как код, следующий за этим, все еще использует b. -- На самом деле после повторного прочтения документации static_pointer_cast я ошибаюсь. Он возвращает общий указатель, который будет использоваться совместно с базовым общим указателем. - person John Gordon; 05.04.2017

Это упущение сделано намеренно, потому что, несмотря на свое название, std::weak_ptr не является типом указателя и не предоставляет интерфейс указателя (оператор ->, оператор *, static_pointer_cast и т. д.).

person Boris Rasin    schedule 26.11.2014