std::initializer_list和std::make_shared:参数过多...需要0个,但提供了3个

3

这些错误消息并没有让我变得更聪明。

godbolt上的最小(不)工作示例

#include <initializer_list>
#include <memory>
#include <vector>


struct S
{
    int j;
    double y;
    std::vector<int> data;
    S(int i, double x, std::initializer_list<int> list)
    : j(i)
    , y(x)
    , data(list)
    {

    }
};

int main()
{
    auto ptr = std::make_shared<S>(1, 1.2, {1,2,3}); // I want this to work
// auto ptr = std::make_shared<S>(1, 1.2, std::initializer_list<int>({1,2,3})); // works
}

错误:

<source>:22:35: error: too many arguments to function 'std::shared_ptr<_Tp>  std::make_shared(_Args&& ...) [with _Tp = S; _Args = {}]'
   22 |     auto ptr = std::make_shared<S>(1, 1.2, {1,2,3});

<source>:11:5: note: candidate: 'S::S(int, double, std::initializer_list<int>)'
   11 |     S(int i, double x, std::initializer_list<int> list)
      |     ^
<source>:11:5: note:   candidate expects 3 arguments, 0 provided

当我在{1,2,3}前调用std::initializer_list<int>的显式构造函数时,编译可以通过。有没有办法规避这个问题,使得我的std::make_shared不会变得臃肿?


这个回答解决了你的问题吗?std::shared_ptr和初始化列表 - InUser
相关:std::make_shared with std::initializer_list 和 https://dev59.com/GF8d5IYBdhLWcg3w1VI1 - user17732522
不,正如我的代码所示,我知道如何通过一个解决方法使其工作。我想知道如何以简洁、简短的形式使用它。 - infinitezero
@infinitezero,您不能仅使用大括号作为参数来使用std::make_shared。您需要创建一个函数,该函数接受正确的参数类型以用于S构造函数,并将其转发到std::make_shared - user17732522
1个回答

3

{1,2,3} 可以是多个东西,并且 make_shared 在参数包展开的时候无法知道它是什么。 如果您不想明确声明长 std::initializer_list<int>{1,2,3},最简单的解决方案是: a. 缩短类型名称:using ints=std::initializer_list<int>; b. 封装调用:

auto make_shared_S(int x, double y, std::initializer_list<int> l)
{
    return std::make_shared<S>(x, y, l);
}

演示: https://godbolt.org/z/WErz87Ks4


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接