Различное поведение при передаче shared_ptr в weak_ptr в функциях потока и обычных функциях

У меня есть функция потока, которая принимает слабый_птр<>, и я передаю свой shared_ptr<> в функцию потока.

С юридической точки зрения слабый_птр<> не должен увеличивать счетчик ссылок в shared_ptr<>, однако, если я не приведу тип с помощью слабого_птр<> при передаче его в функцию потока, он увеличивает счетчик ссылок (неожиданно)

Такое поведение происходит только с функциями потоков, а не с обычными вызовами функций.

Вот код для функции потока

void thrdfn(weak_ptr<int> wp) {
    cout<<wp.use_count()<<endl;  // Prints 2
}

int main() {
    shared_ptr<int> sp = make_shared<int>();
    thread th { thrdfn, (sp)};
    th.join();
    return 0;
}

Тем не менее, когда я typecast при создании потока, он ведет себя правильно

void thrdfn(weak_ptr<int> wp) {
    cout<<wp.use_count()<<endl;  // Prints 1
}

int main() {
    thread th { thrdfn, weak_ptr<int>(sp)}; // typecast 
}

Когда я вызываю функцию как обычный вызов функции, она прекрасно работает без приведения типов

void thrdfn(weak_ptr<int> wp) {
    cout<<wp.use_count()<<endl;  // Prints 1
}

int main() {
    shared_ptr<int> sp = make_shared<int>();
    thrdfn(sp);
    return 0;
}

Поведение одинаково с несколькими компиляторами

2 ответа

Когда вы пишете построить std::thread (и я убрал лишние скобки):

thread th{thrdfn, sp};

Что происходит, это:

Новый поток выполнения начинает выполняться

std::invoke(decay_copy(std::forward<Function>(f)), decay_copy(std::forward<Args>(args))...);

где decay_copy определяется как

template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }

Что сказать, ваш shared_ptr копируется в поток, и вы берете weak_ptr от этой копии. Итак, есть два shared_ptr s: ваш и thread "S.

Старайтесь не пытаться автоматически конвертировать из shared_ptr в weak_ptr, это может создать дополнительный shared_ptr. Ниже фрагмент должен работать нормально:

shared_ptr<int> sp = make_shared<int>();
weak_ptr<int> weak = sp;
thread th { thrdfn, (weak)};
Другие вопросы по тегам