发送模板参数包到 std::basic_ostream
Sending a template parameter pack to std::basic_ostream
cppreference page 上有一个代码示例 std::integer_sequence
:
template<typename T, T... ints>
void print_sequence(std::integer_sequence<T, ints...> int_seq)
{
std::cout << "The sequence of size " << int_seq.size() << ": ";
((std::cout << ints << ' '),...);
std::cout << '\n';
}
我不太明白 ((std::cout << ints << ' '),...)
语法。我没有看到 std::basic_ostream::operator<<` 的任何重载版本,它们会采用可变参数模板的参数包。
这里到底发生了什么,它是如何工作的?
I don't quite understand the ((std::cout << ints << ' '),...)
syntax. I don't see any overloaded versions of std::basic_ostream::operator<<
that would take a variadic template's parameter pack in.
What exactly is happening here, and how does it work?
如果我没记错的话,它叫做 "fold expression",但您也可以将其称为“模板折叠”或简称为“折叠”。
从 C++17 开始可用。
我们的想法是对可变值包应用一个运算符。
经典例子:求和。
如果您想要 ints
的总和,您可以按如下方式应用 +
运算符
( ints + ... );
在您的例子中,折叠表达式应用于逗号运算符。
因此,如果 ints...
是(例如)2, 3, 5, 7
,您的表达式:
((std::cout << ints << ' '),...);
等同于
(std::cout << 2 << ' '), (std::cout << 3 << ' '), (std::cout << 5 << ' '), (std::cout << 7 << ' ');
operator<<
不需要接受可变参数包就可以工作。这里实际发生的是,例如,对于 3 个整数,该行将扩展为如下所示:
(
(std::cout << int1 << ' '),
(std::cout << int2 << ' '),
(std::cout << int3 << ' ')
);
运算符,
保证从左到右的执行顺序。
cppreference page 上有一个代码示例 std::integer_sequence
:
template<typename T, T... ints>
void print_sequence(std::integer_sequence<T, ints...> int_seq)
{
std::cout << "The sequence of size " << int_seq.size() << ": ";
((std::cout << ints << ' '),...);
std::cout << '\n';
}
我不太明白 ((std::cout << ints << ' '),...)
语法。我没有看到 std::basic_ostream::operator<<` 的任何重载版本,它们会采用可变参数模板的参数包。
这里到底发生了什么,它是如何工作的?
I don't quite understand the
((std::cout << ints << ' '),...)
syntax. I don't see any overloaded versions ofstd::basic_ostream::operator<<
that would take a variadic template's parameter pack in.What exactly is happening here, and how does it work?
如果我没记错的话,它叫做 "fold expression",但您也可以将其称为“模板折叠”或简称为“折叠”。
从 C++17 开始可用。
我们的想法是对可变值包应用一个运算符。
经典例子:求和。
如果您想要 ints
的总和,您可以按如下方式应用 +
运算符
( ints + ... );
在您的例子中,折叠表达式应用于逗号运算符。
因此,如果 ints...
是(例如)2, 3, 5, 7
,您的表达式:
((std::cout << ints << ' '),...);
等同于
(std::cout << 2 << ' '), (std::cout << 3 << ' '), (std::cout << 5 << ' '), (std::cout << 7 << ' ');
operator<<
不需要接受可变参数包就可以工作。这里实际发生的是,例如,对于 3 个整数,该行将扩展为如下所示:
(
(std::cout << int1 << ' '),
(std::cout << int2 << ' '),
(std::cout << int3 << ' ')
);
运算符,
保证从左到右的执行顺序。