Why arguments moved twice when constructing std::thread

烈酒焚心 提交于 2020-03-10 04:18:11

问题


Consider this program that essentially creates std::thread that calls the function func() with arg as argument:

#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();
}

My output is

copy ctor
move ctor
move ctor

As far as I understand arg is copied internally in the thread object and then passed to func() as an rvalue (moved). So, I expect one copy construction and one move construction.

Why is there a second move construction?


回答1:


You pass argument to func by value which should constitute the second move. Apparently std::thread stores it internally one more time before calling func, which AFAIK is absolutely legal in terms of the Standard.




回答2:


So, I expect one copy construction and one move construction.

The standard doesn't actually say that. An implementation is allowed to do extra internal move constructions.

Doing so is potentially less efficient though. This was https://gcc.gnu.org/PR69724 and has been fixed for the upcoming GCC 10 release.



来源:https://stackoverflow.com/questions/59601840/why-arguments-moved-twice-when-constructing-stdthread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!