可变参数扩展是否可以用作逗号 - 运算符调用链? [英] Can variadic expansions be used as a chain of comma-operator calls?

查看:127
本文介绍了可变参数扩展是否可以用作逗号 - 运算符调用链?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在查看如何正确使用可变参数模板



这是一个变种的答案:

  inline void inc(){} 

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

由于可变参数会扩展为逗号元素,是等效于模板/函数参数分隔符的那些逗号语义,或者它们插入词法,使它们适合于任何(后处理器)

  / 

/使用相同的零参数inc

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

但是当我尝试:

  //使用相同的零参数inc

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



我不断收到解析错误,之前的...,并且args不会得到它的扩展。为什么不工作?是因为如果args是空的,我们得到一个无效的标点符号点?是合法的,我的编译器不够好吗?



(我已经尝试过括号中的args,和/或使用post-increment; 。)

解决方案

开箱只能在特定上下文中使用,逗号分隔的语句不属于它们。使用你的话:扩展是语义上而不是词法。然而,这并不重要,因为有其他几种方法。已经有某种类型的模式/习惯用来编写简单的可变函数。一种实现方式:



使用帮助模板函数,完全不做任何事情:

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

逗号运算符,将表达式传递到此函数:

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

您可以在扩展中使用逗号运算符,更复杂。如果某些运算符++ 有返回类型 void

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


I was looking at "How to properly use references with variadic templates," and wondered how far comma expansion can 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?

This works on my 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. Why doesn't it work? Is it because if "args" is empty, we get an invalid blob of punctuation? Is it legal, and my compiler isn't good enough?

(I've tried surrounding "args" in parentheses, and/or use post-increment; neither worked.)

解决方案

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:

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

这篇关于可变参数扩展是否可以用作逗号 - 运算符调用链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆