gpt4 book ai didi

c++ - 在 std::array 中使用时无法从 std::function 构造类

转载 作者:行者123 更新时间:2023-12-01 19:13:55 25 4
gpt4 key购买 nike

我想要一个std:arraystd::function ,但我想确保数组的所有元素都已初始化。为此,我构建了一个包装类,它采用 std::function作为构造参数。

但是,当我直接使用我的函数(应该位于 std::function 内的函数)初始化包装类的数组时,它无法编译。

这是问题,经过提炼:

#include <functional>
#include <array>

static void f() {}
using F = std::function<void(void)>;
enum { Count = 4 };

struct C
{
//To get a compilation error when some
// elements of the array are not initialized.
C() = delete;

C(F) {}
};

//OK
static const C c {f};

//OK
static const std::array<F,Count> direct
{
F{f},
{f},
f,
f
};

static const std::array<C,Count> wrapper
{
F{f}, //OK
C{f}, //OK
{f}, //OK
f //could not convert 'f' from 'void()' to 'C'
};

我尝试将数组更改为 std::vector<C> (尽管它违背了我使用 std:array 的全部目的)并且它拒绝编译任何上述初始化。

最佳答案

direct initialization 中的 C c = f; (即 aggregate initialization )不同,每个元素都是 copy initialized .

Each direct public base, (since C++17) array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.

这意味着,wrapper 的最后一个元素(类型为 C)是从 f 复制初始化的;这需要两次隐式转换。从函数指针到F的转换,以及从FC的转换。两者都是用户定义的转换,但一个隐式转换序列中只允许有一种用户定义的转换。

出于同样的原因,C c = f; 也失败了。

您可以添加显式转换。例如

static const std::array<C,Count> wrapper
{
F{f}, //OK
C{f}, //OK
{f}, //OK
static_cast<F>(f)
};

static const C c {f}; 有效,因为它是 direct initialization并且与 copy initialization 的行为不同。对于直接初始化,将考虑 C 的构造函数,其中一个需要 F 作为参数,f 可以转换为 F 那么一切都很好;这里只需要一种用户定义的转换。

(强调我的)

In addition, the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.

关于c++ - 在 std::array 中使用时无法从 std::function 构造类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58620532/

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