gpt4 book ai didi

c++ - 直接初始化!=从不同类型转换时复制初始化?

转载 作者:行者123 更新时间:2023-12-02 17:58:03 25 4
gpt4 key购买 nike

我一直认为对于与类类型不匹配的类型 T 的直接初始化和复制初始化是绝对相等的。但我似乎误会了。如果我复制初始化(使用 = ),以下代码不会编译,并且仅当我通过括号 () 直接初始化时才编译(在任何情况下,代码在终止时都不会工作,但那就是一个不同的故事,与这个问题无关)。

Demo

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

错误:

<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 | };
| ~

cppreference声明以下复制初始化内容:

对于 T = U 的情况:

Otherwise, if T is a class type, and the cv-unqualified version of thetype of other is not T or derived from T, or if T is non-class type,but the type of other is a class type, user-defined conversionsequences that can convert from the type of other to T (or to a typederived from T if T is a class type and a conversion function isavailable) are examined and the best one is selected through overloadresolution. The result of the conversion, which is a rvalue temporary(until C++11)prvalue temporary (since C++11)(until C++17)prvalueexpression (since C++17) of the cv-unqualified version of T if aconverting constructor was used, is then used to direct-initialize theobject. The last step is usually optimized out and the result of theconversion is constructed directly in the memory allocated for thetarget object, but the appropriate constructor (move or copy) isrequired to be accessible even though it's not used. (until C++17)

正如此处所述,我期望 std::package_task 的构造函数,其调用与 std::function 基本相同。 ,将使转换序列可用,因为 lambda 可以转换为 std::packaged_task ,例如直接初始化的情况。但这似乎并没有发生。我忽略了什么?

最佳答案

这是由于 constructor of std::packaged_task<int()> explicit 。来自 cppreference/explicit :

Specifies that a constructor or conversion function (since C++11)or deduction guide (since C++17) is explicit, that is, it cannot be used for implicit conversions and copy-initialization.

构造函数是完美匹配(模板参数 T 匹配任何内容),但它不是可行的用户定义转换序列(并且也没有其他可行的从 lambda 到 std::packaged_task<int()> 的转换)。它失败的原因与此相同:

struct foo { };

struct bar {
explicit bar(foo){}
};

int main() {
foo f;
bar b = f;
}

Live :

<source>:9:13: error: conversion from 'foo' to non-scalar type 'bar' requested
9 | bar b = f;
| ^

同时,删除 explicit ( https://godbolt.org/z/cPx97zx1e ) 或使用 bar b(f); ( https://godbolt.org/z/WMYrb18P8 ) 不是一个错误。

请注意,将上面的构造函数替换为模板化构造函数( the error/witout explicit/calling the constructor explicitly )时,情况不会改变。

关于c++ - 直接初始化!=从不同类型转换时复制初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75172490/

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