【问题标题】:When is an ellipsis needed when dealing with parameter packs?处理参数包时何时需要省略号?
【发布时间】:2021-09-24 19:12:25
【问题描述】:

我正在努力理解some code from cppreference.com。相关部分在这里

template<typename... Ts>
std::ostream& operator<<(std::ostream& os, std::tuple<Ts...> const& theTuple)
{
    std::apply
    (
        [&os](Ts const&... tupleArgs)
        {
            os << '[';
            std::size_t n{ 0 };
            ((os << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...);
            os << ']';
        }, theTuple
    );
    return os;
}

如果我正确解释上述内容,((os &lt;&lt; tupleArgs &lt;&lt; (++n != sizeof...(Ts) ? ", " : "")), ...) 是逗号运算符上的折叠表达式。语义上是([some pattern involving the parameter pack's values] , ...),意思是用逗号折叠。

但我不明白为什么里面的sizeofsizeof...?对我来说,省略号意味着扩展,但我们不想在那里扩展。 Ts 就像一个聚合类型,类似于元组,我们只需要编译时聚合类型的大小,同时编译器评估折叠。事实上,在 Visual Studio 中,无论有没有省略号,它都可以工作。在 GCC 中也是如此,Godbolt 告诉我。 (编辑:实际上我错了没有它编译的省略号,但输出包含一个不应该存在的尾随逗号)

如果您想要参数包的大小,规则是否总是使用sizeof...

【问题讨论】:

  • “事实上,在 Visual Studio 中,不管有没有省略号,它都可以工作” - 我怀疑你的测试并不完全。
  • 啊我的错。输出中不应该有一个尾随逗号。我很惊讶它编译并没有注意到
  • 所以sizeof(Ts) 将在展开时返回单个类型的大小,而sizeof...(Ts) 返回包的大小?
  • 是的。总结一下。

标签: c++ variadic-templates parameter-pack


【解决方案1】:

那里需要省略号,因为sizeof...(Ts)sizeof 的一种特殊形式,它返回参数包的大小。普通的 sizeof(Ts) 不能用于此目的,因为它需要保持可以在扩展模式中使用标准 sizeof 行为,即 sizeof(Ts) 在评估的折叠表达式中返回单个类型的大小。

【讨论】:

    猜你喜欢
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2012-12-29
    • 2013-06-27
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多