将多个参数传递给流运算符
Pass multiple arguments to stream operator
我有一个 class,让我们用可变模板参数称它为 Sample
。此 class 包含一个函数 run(Args... args)
。这个 class 还实现了调用此函数的流运算符。
class 看起来像这样:
template<typename ...Args>
class Sample
{
void run(Args... args)
{
// do something
}
Sample& operator<<(const tuple<Args...>& args)
{
run(unpack_somehow(args)...);
return *this;
}
};
现在我想使用流运算符连接多个调用,通过元组的大括号初始化传递参数:
void main()
{
Sample<int, string, int> s;
// doesn't work :(
s << {1, "msg", 2} << {1, "msg", 2};
}
我知道我可以只写 make_tuple(1, "msg", 2)
并且它会起作用,但我正在寻找不需要像 make_tuple
.
这样的额外函数调用的解决方案
有没有办法实现这样一个功能,我可以在大括号中传递参数(或者可能通过重载逗号运算符来使用逗号分隔)?
当您使用行 s << {1, "msg", 2} << {1, "msg", 2};
时,它不会为 C++ 编译器提供足够的信息来推断这些初始化列表的含义。
除非你给编译器一个提示(使用 make_tuple
或传递一个实际的 tuple
变量)它不会知道你的意思并且将无法调用适当的 operator<<()
.
看来你运气不好。这不能以您发布问题的方式完成。
Initializer-lists 未在操作员端启用。
它们在 right-hand 端未启用,因为它们在 left-hand 端未启用,并且它们在 left-hand 端未启用,因为那也会构成对解析器来说是一个巨大的挑战。
至于这样做的原因,Stroustrup 和 Dos Reis 在 2007 年发表的 draft/discussion paper N2215 对 [=28= 的许多问题提供了很多见解] 在各种情况下。具体来说,有一个关于二元运算符的部分(第 6.2 节):
Consider more general uses of initializer lists. For example:
v = v+{3,4};
v = {6,7}+v;
When we consider operators as syntactic sugar for functions, we naturally consider the above equivalent to
v = operator+(v,{3,4});
v = operator+({6,7},v);
It is therefore natural to extend the use of initializer lists to expressions. There are many uses where initializer lists combined with operators is a “natural” notation.
However, it is not trivial to write a LR(1) grammar that allows arbitrary use of initializer lists. A block also starts with a { so allowing an initializer list as the first (leftmost) entity of an expression would lead to chaos in the grammar.
It is trivial to allow initializer lists as the right-hand operand of binary operators, in
subscripts, and similar isolated parts of the grammar. The real problem is to allow ;a={1,2}+b;
as an assignment-statement without also allowing ;{1,2}+b;
. We suspect that allowing initializer lists as right-hand, but nor [sic] as left-hand arguments to most operators is too much of a kludge, [...]
我有一个 class,让我们用可变模板参数称它为 Sample
。此 class 包含一个函数 run(Args... args)
。这个 class 还实现了调用此函数的流运算符。
class 看起来像这样:
template<typename ...Args>
class Sample
{
void run(Args... args)
{
// do something
}
Sample& operator<<(const tuple<Args...>& args)
{
run(unpack_somehow(args)...);
return *this;
}
};
现在我想使用流运算符连接多个调用,通过元组的大括号初始化传递参数:
void main()
{
Sample<int, string, int> s;
// doesn't work :(
s << {1, "msg", 2} << {1, "msg", 2};
}
我知道我可以只写 make_tuple(1, "msg", 2)
并且它会起作用,但我正在寻找不需要像 make_tuple
.
有没有办法实现这样一个功能,我可以在大括号中传递参数(或者可能通过重载逗号运算符来使用逗号分隔)?
当您使用行 s << {1, "msg", 2} << {1, "msg", 2};
时,它不会为 C++ 编译器提供足够的信息来推断这些初始化列表的含义。
除非你给编译器一个提示(使用 make_tuple
或传递一个实际的 tuple
变量)它不会知道你的意思并且将无法调用适当的 operator<<()
.
看来你运气不好。这不能以您发布问题的方式完成。
Initializer-lists 未在操作员端启用。
它们在 right-hand 端未启用,因为它们在 left-hand 端未启用,并且它们在 left-hand 端未启用,因为那也会构成对解析器来说是一个巨大的挑战。
至于这样做的原因,Stroustrup 和 Dos Reis 在 2007 年发表的 draft/discussion paper N2215 对 [=28= 的许多问题提供了很多见解] 在各种情况下。具体来说,有一个关于二元运算符的部分(第 6.2 节):
Consider more general uses of initializer lists. For example:
v = v+{3,4}; v = {6,7}+v;
When we consider operators as syntactic sugar for functions, we naturally consider the above equivalent to
v = operator+(v,{3,4}); v = operator+({6,7},v);
It is therefore natural to extend the use of initializer lists to expressions. There are many uses where initializer lists combined with operators is a “natural” notation.
However, it is not trivial to write a LR(1) grammar that allows arbitrary use of initializer lists. A block also starts with a { so allowing an initializer list as the first (leftmost) entity of an expression would lead to chaos in the grammar.
It is trivial to allow initializer lists as the right-hand operand of binary operators, in subscripts, and similar isolated parts of the grammar. The real problem is to allow;a={1,2}+b;
as an assignment-statement without also allowing;{1,2}+b;
. We suspect that allowing initializer lists as right-hand, but nor [sic] as left-hand arguments to most operators is too much of a kludge, [...]