【问题标题】:I've found a parameter pack expansion here on the board and I don't understand what exactly is going [duplicate]我在板上找到了一个参数包扩展,我不明白到底发生了什么[重复]
【发布时间】:2016-06-18 20:33:30
【问题描述】:

我在板上看到了一个我不明白的code snippet

struct expression_sequence
{
    template<typename... Ts>
    expression_sequence(Ts&&... ts) { }
};

template<typename T, class Tuple = std::vector<T>>
class vector
{
public:    
    template<typename... Elements>
    vector(Elements&&... elements)
    {
        m_elements.reserve(sizeof...(Elements));
        expression_sequence{ (m_elements.push_back(std::forward<Elements>(elements)), 0)... };
    }

private:
    Tuple m_elements;
};

expression_sequence{ (m_elements.push_back(std::forward&lt;Elements&gt;(elements)), 0)... };究竟发生了什么,为什么它在工作?

我不明白为什么我们需要用(, 0) 包围m_elements.push_back(std::forward&lt;Elements&gt;(elements))。 (为什么是0,即为什么是int?)。还有(m_elements.push_back(std::forward&lt;Elements&gt;(elements)), 0)的类型是什么?

【问题讨论】:

    标签: c++ templates c++14 variadic-templates


    【解决方案1】:

    这是一种解决方法,等待fold expression

    目前,push_back 仅接受一个元素,因此您无法解压缩参数列表。
    使用该技巧,通过类及其(让我说)可变参数构造函数,您可以成功解包参数包,但该类仍然需要一个类型列表,即使它不使用这些参数。
    因此,使用周围的部分 (, 0) 您实际上允许支持结构从 ints 列表中自动推断其类型,以便该代码编译。

    有人可能会说支持结构完全没用。
    当然,这不过是个技巧,因为折叠表达式是为修订版C++17计划的。

    【讨论】:

    • 我还是不明白为什么(m_elements.push_back(std::forward&lt;Elements&gt;(elements)), 0) 在语法上是正确的。 push_back 具有返回类型 void。那么,这个表达式的类型是什么?我注意到我可以写auto x = (1, 1, 1); 并且x 的类型是int。那里发生了什么?
    • 以前从未听说过comma operator
    • 啊,我明白了。因此,对于任何void foo() { },表达式(foo(), 0) 的类型是int,对吧?在这种情况下,第一个表达式是一个参数包。但是,这里的表达式类型也是int。 (我猜这实际上是错误的,因为第一个表达式是这里的参数包)。我有一些问题要理解为什么(m_elements.push_back(std::forward&lt;Elements&gt;(elements)), 0) 是一个我们可以扩展的参数包。
    • @0xbadf00d 该表达式不是参数包。 elementsElements 是。可以扩展包含包的表达式。
    猜你喜欢
    • 2018-01-27
    • 2012-10-18
    • 1970-01-01
    • 2018-08-25
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多