mardi 21 janvier 2020

std::packaged_task should have deleted copy c'tor with const parameter

Link https://cplusplus.github.io/LWG/issue2067 provides the following discussion:

Class template packaged_task is a move-only type with the following form of the deleted copy operations: packaged_task(packaged_task&) = delete;
packaged_task& operator=(packaged_task&) = delete;
Note that the argument types are non-const. This does not look like a typo to me, this form seems to exist from the very first proposing paper on N2276. Using either of form of the copy-constructor did not make much difference before the introduction of defaulted special member functions, but it makes now an observable difference. This was brought to my attention by a question on a German C++ newsgroup where the question was raised why the following code does not compile on a recent gcc:

#include <utility>
#include <future>
#include <iostream>
#include <thread>

int main() {
  std::packaged_task<void()> someTask([]{ std::cout << std::this_thread::get_id() << std::endl; });
  std::thread someThread(std::move(someTask)); // Error here
// Remainder omitted
}

It turned out that the error was produced by the instantiation of some return type of std::bind which used a defaulted copy-constructor, which leads to a const declaration conflict with [class.copy] p8.

Some aspects of this problem are possibly core-language related, but I consider it more than a service to programmers, if the library would declare the usual form of the copy operations (i.e. those with const first parameter type) as deleted for packaged_task to prevent such problems.

Could anybody explain the meaning of the marked statement? I don't undestand how the missing const qualifer affects the compilation process, and how this behavior is explained in standard. What is the point of adding const to the parameter of the deleted copy constructor?

Aucun commentaire:

Enregistrer un commentaire