Почему аргументы перемещаются дважды при построении std :: thread - PullRequest
4 голосов
/ 05 января 2020

Рассмотрим эту программу, которая по существу создает std::thread, которая вызывает функцию func() с arg в качестве аргумента:

#include <thread>
#include <iostream>

struct foo {
   foo() = default;
   foo(const foo&) { std::cout << "copy ctor" << std::endl; }
   foo(foo&&) noexcept { std::cout << "move ctor" << std::endl; }
};

void func(foo){}

int main() {
   foo arg;
   std::thread th(func, arg);
   th.join();
}

Мой вывод

copy ctor
move ctor
move ctor

Насколько Я понимаю, что arg копируется внутри объекта потока и затем передается в func() как значение (перемещено). Итак, я ожидаю одна копия конструкции и одна конструкция хода .

Почему существует вторая конструкция хода?

Ответы [ 2 ]

3 голосов
/ 05 января 2020

Вы передаете аргумент func по значению, которое должно составлять второй ход. Очевидно, std::thread хранит его внутри еще один раз перед вызовом func, что AFAIK является абсолютно законным с точки зрения Стандарта.

1 голос
/ 05 февраля 2020

Итак, я ожидаю одну конструкцию копии и одну конструкцию перемещения.

Стандарт на самом деле этого не говорит. Реализация может делать дополнительные внутренние перемещения.

Это потенциально менее эффективно. Это было https://gcc.gnu.org/PR69724 и исправлено в предстоящем выпуске G CC 10.

...