Ответ 1
Если вы установите точку останова в конструкторе копирования, вы можете увидеть контекст вызова конструктора в окне "Стек вызовов". В режиме отладки я нашел следующие точки при вызове конструктора:
-
Сначала функциональный объект копируется в вспомогательную функцию
bind
-
Затем функциональный объект перемещается во внутренний функциональный объект
_Bind
-
После этого создается класс для запуска потоков
_LaunchPad
. В
конструктор требует ссылки rvalue на экземпляр _Bind, поэтому мы имеем другой вызов конструктора перемещения -
move конструктор
_LaunchPad
вызывается, когда его копия создается в новом потоке.
Таким образом, у вас есть 4 вызова конструктора копирования в вашем случае. Если вы добавили конструктор перемещения, вы увидите 1 конструктор копирования и 3 вызова конструктора.
В режиме освобождения все пустые вызовы конструктора устранены, а код ассемблера выглядит довольно просто.