gpt4 book ai didi

c++ - std::packaged_task 应该删除带有 const 参数的拷贝 c'tor

转载 作者:行者123 更新时间:2023-12-02 15:08:33 25 4
gpt4 key购买 nike

链接 https://cplusplus.github.io/LWG/issue2067提供以下讨论:

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.

谁能解释一下标记语句的含义吗?我不明白缺少的 const 限定符如何影响编译过程,以及标准中如何解释这种行为。删除的复制构造函数的参数中添加const有什么意义?

最佳答案

这是一个toy example :

struct problem {
problem()=default;
problem(problem&&)=default;
problem(problem&)=delete;
};

template<class T>
struct bob {
T t;
bob()=default;
bob(bob&&)=default;
bob(bob const&)=default;
};

int main() {
problem p;
problem p2 = std::move(p);
bob<problem> b;
bob<problem> b2 = std::move(b);
}

bob<problem>无法编译,因为 bob(bob const&)=defaultproblem(problem&)=delete 交互时出错.

可以说,当标准“应该”确定它无法实现 bob(bob const&) 时,它会干净地出错。 ,并对待 =default=delete (就像我们有 problem(problem const&)=delete 一样),但是在这个极端情况的极端情况下,标准措辞不会是完美的。极端情况的这个角落将会非常奇怪和古怪,我不确定使它翻译的一般规则 =default=delete是对的!

修复如果我们 problem(problem const&)=delete (嗯,到 packaged_task )将比我们对 =default 所做的任何事情都要干净得多。构造者规则。

现在标准探究:

首先,很明显 bob<problem> 的隐式声明的复制构造函数上面会有签名bob(bob&)[class.ctor]中。我什至不会引用这个标准,因为我很懒。

我们明确默认 bob(bob const&)复制构造函数,其签名与隐式声明的签名不同。

有关于显式默认函数的规则,它们与签名的冲突在 11.4.2 中。

在显式默认函数中[dcl.fct.def.default] 11.4.2/2

2 The typeT1of an explicitly defaulted function F is allowed to differ from the type T2 it would have had if it were implicitly declared, as follows:

—(2.1) T1 and T2 may have differing ref-qualifiers; and

—(2.2) if T2 has a parameter of type const C&, the corresponding parameter of T1 may be of type C&.

If T1 differs from T2 in any other way, then:

—(2.3) if F is an assignment operator, and the return type of T1 differs from the return type of T2 or T1’s parameter type is not a reference, the program is ill-formed;

—(2.4) otherwise, if F is explicitly defaulted on its first declaration, it is defined as deleted;

—(2.5) otherwise, the program is ill-formed.

默认为T1 ,其中包含 const&不是& ,所以 (2.2) 不适用。

我的阅读实际上让它被捕获了(2.4); bob(bob const&)的类型与隐式声明的 bob(bob&) 不同以不被允许的方式;但第一个声明是 default编辑,所以应该是 delete d.

我正在查看n4713 draft version ;也许旧版本没有该条款。

关于c++ - std::packaged_task 应该删除带有 const 参数的拷贝 c'tor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59841698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com