gla*_*des 2 c++ copy-initialization packaged-task direct-initialization
我一直认为对于与类类型不匹配的类型 T 的直接初始化和复制初始化是绝对相等的。但我似乎误会了。如果我复制初始化(使用=),下面的代码不会编译,并且只有当我通过括号()直接初始化时才编译(在任何情况下,代码在终止时都不起作用,但这是一个不同的故事,与这个问题)。
#include <future>
#include <cstdio>
int main()
{
/* This doesn't compile */
// std::packaged_task<int()> foo = []() -> int {
// return 10;
// };
/* This works */
std::packaged_task<int()> foo([]() -> int {
return 10;
});
auto fut = foo.get_future();
foo();
auto a = fut.get();
printf("a == %d\n", a);
}
Run Code Online (Sandbox Code Playgroud)
错误:
<source>: In function 'int main()':
<source>:8:37: error: conversion from 'main()::<lambda()>' to non-scalar type 'std::packaged_task<int()>' requested
8 | std::packaged_task<int()> foo = []() -> int {
| ^~~~~~~~~~~~~
9 | return 10;
| ~~~~~~~~~~
10 | };
| ~
Run Code Online (Sandbox Code Playgroud)
cppreference对于复制初始化声明以下内容:
对于 T = U 的情况:
否则,如果 T 是类类型,并且 other 类型的 cv 未限定版本不是 T 或派生自 T,或者如果 T 是非类类型,但 other 类型是类类型,则用户定义检查可以从 other 的类型转换为 T 的转换序列(如果 T 是类类型并且转换函数可用,则转换为从 T 派生的类型),并通过重载决策选择最佳的转换序列。转换的结果,它是 cv 未限定版本的右值临时 (C++11 之前) 纯右值临时 (C++11 起)(C++17 之前) 纯右值表达式 (C++17 起) T 如果使用了转换构造函数,则用于直接初始化对象。最后一步通常被优化,转换结果直接在为目标对象分配的内存中构造,但即使不使用适当的构造函数(移动或复制)也需要可访问。(C++17 之前)
如此处所述,我希望 的构造函数std::package_task(它采用与 基本相同的可调用项std::function)将提供一个可用的转换序列,因为 lambda 可以转换为std::packaged_task,例如直接初始化的情况。但这似乎并没有发生。我在忽略什么?
这是由于being的构造函数std::packaged_task<int()>explicit造成的。来自cppreference/explicit:
指定构造函数或转换函数 (C++11 起) 或推导指南 (C++17 起) 是显式的,即它不能用于隐式转换和复制初始化。
构造函数是完美匹配(模板参数T匹配任何内容),但它不是可行的用户定义转换序列(并且也没有其他可行的从 lambda 到 的转换std::packaged_task<int()>)。它失败的原因与此相同:
struct foo { };
struct bar {
explicit bar(foo){}
};
int main() {
foo f;
bar b = f;
}
Run Code Online (Sandbox Code Playgroud)
居住:
<source>:9:13: error: conversion from 'foo' to non-scalar type 'bar' requested
9 | bar b = f;
| ^
Run Code Online (Sandbox Code Playgroud)
同时,删除explicit(https://godbolt.org/z/cPx97zx1e)或使用bar b(f);(https://godbolt.org/z/WMYrb18P8)并不是错误。
请注意,当用模板化构造函数替换上面的构造函数时,事情不会改变(错误/没有显式/显式调用构造函数)。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |