简体   繁体   English

可变参数扩展可以用作逗号运算符调用链吗?

[英]Can variadic expansions be used as a chain of comma-operator calls?

I was looking at " How to properly use references with variadic templates ," and wondered how far comma expansion can go.我在看“ 如何正确使用可变参数模板的引用”,想知道逗号扩展可以多远 go。

Here's a variant of the answer:这是答案的一个变体:

inline void inc() { }

template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t; inc(args...); }

Since variadic arguments are expanded to a comma -separated list of their elements, are those commas semantically equivalent to template/function-argument separators, or are they inserted lexically , making them suitable for any (post-preprocessor) use, including the comma operator?由于 variadic arguments 被扩展为逗号分隔的元素列表,这些逗号在语义上是否等同于模板/函数参数分隔符,或者它们是否按词法插入,使它们适合任何(后处理器)使用,包括逗号运算符?

This works on my GCC-4.6:这适用于我的 GCC-4.6:

// Use the same zero-argument "inc"

template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t, inc(args...); }

But when I tried:但是当我尝试时:

// Use the same zero-argument "inc"

template<typename T,typename ...Args>
inline void inc(T& t, Args& ...args) { ++t, ++args...; }

I kept getting parsing errors, expecting the ";"我不断收到解析错误,期待“;” before the "...", and that "args" won't get its pack expanded.在“...”之前,“args”不会扩展其包。 Why doesn't it work?为什么它不起作用? Is it because if "args" is empty, we get an invalid blob of punctuation?是因为如果“args”为空,我们会得到一个无效的标点符号块吗? Is it legal, and my compiler isn't good enough?这是合法的,我的编译器不够好吗?

(I've tried surrounding "args" in parentheses, and/or use post-increment; neither worked.) (我试过将“args”括在括号中,和/或使用后增量;都没有用。)

Unpacking is only allowed in certain contexts, and comma separated statements doesn't belong to them.仅在某些情况下才允许解包,并且逗号分隔的语句不属于它们。 Using your words: The expansion is semantically and not lexically.用你的话:扩展是语义上的而不是词汇上的。 However, it doesn't matter because there are several other ways of doing it.但是,这并不重要,因为还有其他几种方法可以做到这一点。 There are already some kind of patterns/idioms to write simple variadic functions.已经有某种模式/习惯用法来编写简单的可变参数函数。 One way of doing it:一种方法:

Use a helper template function, that does nothing at all:使用一个辅助模板函数,它什么都不做:

template <typename ...Args>
void pass(Args&&...) { }

Instead of using the comma operator, pass the expressions to this function:不使用逗号运算符,而是将表达式传递给此函数:

template <typename ...Args>
void inc(Args&&... args)
{
    pass(++std::forward<Args>(args)...);
}

You can use the comma operator within the expansion, if the expressions have to be more complex.如果表达式必须更复杂,您可以在扩展中使用逗号运算符。 This might be useful in your case, if some operator++ have return type void :如果某些operator++的返回类型为void ,这可能对您有用:

    pass((++std::forward<Args>(args), 0)...);

C++17 added fold expression . C++17 添加了折叠表达式

template<typename ...Args>
inline void inc(Args& ...args) { (++args, ...); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM