0

我试图从 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 << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...)则为逗号运算符上的折叠表达式。从语义上讲,它是([some pattern involving the parameter pack's values] , ...)用逗号折叠的意思。

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

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

4

1 回答 1

0

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

于 2021-09-25T16:23:41.570 回答