gpt4 book ai didi

c++ - std::make_unique(以及 emplace、emplace_back)对 initializer_list 参数的笨拙推导

转载 作者:可可西里 更新时间:2023-11-01 17:44:13 26 4
gpt4 key购买 nike

假设我有这个结构:

struct position
{
int x, y;
};

和另一个将 this 作为构造函数参数的类:

class positioned
{
public:
positioned(position p) : pos(p) {}
private:
position pos;
};

我怎样才能得到简单的

auto bla = std::make_unique<positioned>({1,2});

上类?

目前,编译器试图通过 initializer_list<int> 匹配并调用 make_unique 的数组变体,这很愚蠢,因为 positioned只有一个构造函数。 emplace 出现同样的问题和 emplace_back功能。几乎所有将其可变模板参数转发给类的构造函数的函数似乎都表现出这种行为。

我明白我可以通过以下方式解决这个问题

  1. 给予 positioned一二int参数构造函数并删除 {}在调用 make_unique , 或
  2. 明确指定 make_unique 的参数类型作为position{1,2} .

两者似乎都过于冗长,在我看来(在 make_unique 实现中付出了一些努力),这可以在不过度指定参数类型的情况下解决。

这是 make_unique 中可解决的缺陷吗?实现还是这是一个没有人应该关心的无法解决的、无趣的边缘案例?

最佳答案

当给定花括号初始化列表时,函数模板参数推导不起作用;它仅基于实际表达式起作用。

还应注意 positioned 无论如何都不能从 {1, 2} 列表初始化。这将尝试调用一个双参数构造函数,而 positioned 没有这样的构造函数。您需要使用 positioned({1, 2})positioned{{1, 2}}

因此,一般的解决方案是让 make_unique 以某种方式神奇地为它正在构造的类型重现每个可能的构造函数的签名。这显然不是此时在 C++ 中做的合理事情。

另一种方法是使用 lambda 来创建对象,并编写一个替代的 make 函数,使用 C++17 的保证省略规则将返回的纯右值应用到内部 new 表达式:

template<typename T, typename Func, typename ...Args>
std::unique_ptr<T> inject_unique(Func f, Args &&...args)
{
return std::unique_ptr<T>(new auto(f(std::forward<Args>(args)...)));
}

auto ptr = inject_unique<positioned>([]() {return positioned({1, 2});});

您甚至可以放弃 typename T 参数:

template<typename Func, typename ...Args>
auto inject_unique(Func f, Args &&...args)
{
using out_type = decltype(f(std::forward<Args>(args)...));
return std::unique_ptr<out_type>(new auto(f(std::forward<Args>(args)...)));
}

auto ptr = inject_unique([]() {return positioned({1, 2});});

关于c++ - std::make_unique(以及 emplace、emplace_back)对 initializer_list 参数的笨拙推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48043560/

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