gex*_*ide 25 c++ templates variadic-templates c++11
使用逗号分隔的参数包的最简单方法是什么std::ostream?
例:
template<typename... Args>
void doPrint(std::ostream& out, Args... args){
out << args...; // WRONG! What to write here?
}
// Usage:
int main(){
doPrint(std::cout,34,"bla",15); // Should print: 34,bla,15
}
Run Code Online (Sandbox Code Playgroud)
注意:可以假设<<操作员的相应过载可用于所有类型的参数包.
Pio*_*cki 39
没有你想要的递归调用和逗号.
template <typename Arg, typename... Args>
void doPrint(std::ostream& out, Arg&& arg, Args&&... args)
{
out << std::forward<Arg>(arg);
using expander = int[];
(void)expander{0, (void(out << ',' << std::forward<Args>(args)), 0)...};
}
Run Code Online (Sandbox Code Playgroud)
在c ++ 17中使用折叠表达式:
template <typename Arg, typename... Args>
void doPrint(std::ostream& out, Arg&& arg, Args&&... args)
{
out << std::forward<Arg>(arg);
((out << ',' << std::forward<Args>(args)), ...);
}
Run Code Online (Sandbox Code Playgroud)
M.M*_*M.M 18
在C++ 17中,将有一种更简单的方法(正如Kerrek SB在评论中所暗示的那样;这实际上存在于N4606中,这是第一个C++之后的草案14),称为折叠表达式:
代码是:
(out << ... << args);
Run Code Online (Sandbox Code Playgroud)
并且图案被称为二进制左折叠,其定义是等同于... .expression op ... op parameter-pack((( expression op arg1) op arg2) op arg3)op argN
我认为外部括号对于像这样的表达式语句并不是绝对必要的,但是如果fold表达式是另一个运算符的操作数,则它们是必需的,或者是一个非常好的主意:)
通常的答案是定义两个单独的重载,对于基本情况使用空的重载:
// base case
void doPrint(std::ostream& out) {}
template <typename T, typename... Args>
void doPrint(std::ostream& out, T t, Args... args)
{
out << t; // add comma here, see below
doPrint(out, args...);
}
Run Code Online (Sandbox Code Playgroud)
当然在实际代码中,我不会每次都复制参数,而是使用转发引用,但是你明白了.
如果你想在每个项目之后添加逗号,即使在最后一个项目之后,也只需要替换out << t为out << t << ','.
如果您只想在内部使用逗号,而不是在最后一个元素之后,则需要一个单独的单参数重载,它不会打印逗号,而泛型重载在包之前需要两个不同的参数,即:
template <typename T>
void doPrint(std::ostream& out, T t)
{
out << t;
}
template <typename T, typename U, typename... Args>
void doPrint(std::ostream& out, T t, U u, Args... args)
{
out << t << ',';
doPrint(out, u, args...);
}
Run Code Online (Sandbox Code Playgroud)
参数包扩展仅适用于普通函数调用,而不适用于中缀运算符.因此,您需要将s << x语法转换为普通函数调用语法f(s, x):
template<class Head>
void print_args_(std::ostream& s, Head&& head) {
s << std::forward<Head>(head);
}
template<class Head, class... Tail>
void print_args_(std::ostream& s, Head&& head, Tail&&... tail) {
s << std::forward<Head>(head);
print_args_(s, std::forward<Tail>(tail)...);
}
template<class... Args>
void print_args(Args&&... args) {
print_args_(std::cout, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13063 次 |
| 最近记录: |