如何正确展开包以创建 N 元素数组

Dmi*_*try 6 c++ templates fold-expression c++17

我期望这段代码创建 10 个元素向量,每个向量构造为A{1, 2, 3.0},但实际上输出是1

#include <iostream>
#include <vector>

struct A {
    int a{0};
    int b{0};
    double c{0.0};
};

template<typename T, size_t... Ns>
auto create_array(std::index_sequence<Ns...>, auto&&... args) {
    return std::vector<T> {
        ([&](...){ return std::forward<T>(T{args...}); }(Ns), ...)
    };
}

template<typename T, size_t N>
auto create_array(auto&&... args) {
    return create_array<T>(std::make_index_sequence<N>{}, std::forward<decltype(args)>(args)...);
}

int main() {
    std::cout << create_array<A, 10>(1,2,3.0).size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

怎么会发生这种事,为什么没有正确展开?这里有什么问题吗?我特别想要这条线

([&](...){ return std::forward<T>(T{args...}); }(Ns), ...)
Run Code Online (Sandbox Code Playgroud)

成为

[&](...){ return std::forward<T>(T{args...}); }(0),
[&](...){ return std::forward<T>(T{args...}); }(1),
[&](...){ return std::forward<T>(T{args...}); }(2),
//...
Run Code Online (Sandbox Code Playgroud)

yur*_*hek 5

return std::vector<T> {
    ([&](...){ return std::forward<T>(T{args...}); }(Ns), ...)
};
Run Code Online (Sandbox Code Playgroud)

解压到

return std::vector<T> {
    ([&](...){ return std::forward<T>(T{args...}); }(0),
     [&](...){ return std::forward<T>(T{args...}); }(1),
     [&](...){ return std::forward<T>(T{args...}); }(2),
     /* etc */)
};
Run Code Online (Sandbox Code Playgroud)

这是一个带括号的逗号运算符链,其计算结果为序列中的最后一个表达式。您想简单地解压到向量参数中,而不使用折叠表达式:

return std::vector<T> {
    [&](...){ return std::forward<T>(T{args...}); }(Ns)...
};
Run Code Online (Sandbox Code Playgroud)


Nel*_*eal 2

你提到的那一行:

([&](...){ return std::forward<T>(T{args...}); }(Ns), ...)
Run Code Online (Sandbox Code Playgroud)

是一个折叠表达式。它只返回最后一个值,因为这就是逗号运算符的工作原理。删除括号和逗号,将表达式扩展Ns为初始值设定项列表:

template<typename T, size_t... Ns>
auto create_array(std::index_sequence<Ns...>, auto&&... args) {
    return std::vector<T> {
        [&](...){ return std::forward<T>(T{args...}); }(Ns)...
    };
}
Run Code Online (Sandbox Code Playgroud)