如何在C++中将运算符 <<(或 >>)应用于参数包?

huangapple go评论72阅读模式
英文:

How to apply operator << (or >>) to a parameter pack in C++?

问题

请注意,由于您的原始文本中包含HTML编码,我将翻译其内容,但将HTML编码保留为原样。以下是您要翻译的内容:

假设我有这个函数模板:

template<auto& ... FLAGS>
void function(const char *c_str) {
    std::stringstream strs;
    //((strs << FLAGS)...); // <-- how do I do this?
    strs << c_str;
    .
    .
    .
}

考虑到函数模板将像这样使用:

function<std::dec, std::left>("123");

如何在参数包中的每个参数上应用 << 运算符(使用对象 strs )?

我已经找到了一个引入助手函数的解决方法:

void unpack(const auto& ...){};

并在原始函数模板中使用:

unpack((strs << FLAGS)...);

但我想知道是否有更好的方法!

英文:

Imagine I have this function template:

template&lt;auto&amp; ... FLAGS&gt;
void function(const char *c_str) {
    std::stringstream strs;
    //((strs &lt;&lt; FLAGS)...); // &lt;-- how do I do this?
    strs &lt;&lt; c_str;
    .
    .
    .
}

Consider that the function template is going to be used like this:

function&lt;std::dec, std::left&gt;(&quot;123&quot;);

how to apply the operator &lt;&lt; on each parameter from the parameter pack (with the object strs )?

I have already found a workaround with introducing a helper function:

void unpack(const auto&amp; ...){};

And in the original function template:

unpack((strs &lt;&lt; FLAGS)...);

But I was wondering if there is a better way to this!

答案1

得分: 1

表达式

strs << FLAG1 << FLAG2 << FLAG3;

等同于

(((strs << FLAG1) << FLAG2) << FLAG3);

你需要链接运算符,因此你需要折叠表达式的形式

( *cast-expression* fold-operator ... fold-operator cast-expression )

其中 fold-operator 是 stringstream::operator<<

(strs << ... << FLAGS);
英文:

The expression

strs &lt;&lt; FLAG1 &lt;&lt; FLAG2 &lt;&lt; FLAG3;

is equal to

(((strs &lt;&lt; FLAG1) &lt;&lt; FLAG2) &lt;&lt; FLAG3);

You have to chain operators, therefore you need the form of fold-expression

> ( cast-expression fold-operator ... fold-operator cast-expression )

where fold-operator is stringstream::operator&lt;&lt;

(strs &lt;&lt; ... &lt;&lt; FLAGS);

答案2

得分: 1

使用,运算符而不是<<运算符来进行折叠,将会产生类似以下的结果:

str << FLAG1;
str << FLAG2;
...

(实际上,你需要使用,而不是;,但结果逻辑是相同的)。

template<auto& ... FLAGS>
void function(int c_str) {
    std::stringstream strs;
    ((strs << FLAGS), ...);
    //              ^
    strs << c_str;
}
英文:

Instead a fold with the &lt;&lt; operator, you could also fold with the , operator, which would produce something like

str &lt;&lt; FLAG1;
str &lt;&lt; FLAG2;
...

(actually you'd need to use , instead of ; but the resulting logic is the same).

template&lt;auto&amp; ... FLAGS&gt;
void function(int c_str) {
    std::stringstream strs;
    ((strs &lt;&lt; FLAGS), ...);
    //              ^
    strs &lt;&lt; c_str;
}

huangapple
  • 本文由 发表于 2023年5月29日 12:42:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354719.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定