c++ 11可变模板和逗号分隔表达式的等价性
C++11 variadic templates and comma-separated expressions equivalence
在可变变量模板中…操作符将参数包展开为一系列以逗号分隔的参数(以最简单的形式)。我的问题是:为什么调用some_function()为多个参数逗号分隔工作,并调用它与…运营商不?
我说的是这段代码:
template<typename... Args> inline void expand(Args&&... args)
{
some_function(22),some_function(32); // Works
some_function(args)...; // Doesn't work - ERROR
}
这两行不应该产生类似的输出吗?
如另一个答案所述,展开参数包得到的逗号不是逗号操作符,而是参数列表。将参数列表作为表达式显然是错误的。由于您不需要函数的返回值,您可以尝试以下行:
template <class... T>
void ignore(T&&...) {}
template<typename... Args> inline void expand(Args&&... args)
{
ignore(some_function(args)...);
}
如果some_function
返回void
,则包扩展将不起作用,因为您不能给函数提供无效的"值"。您可以返回一个值,也可以用逗号操作符将some_function
的每次调用链接起来:
template<typename... Args> inline void expand(Args&&... args)
{
ignore( (some_function(args),true)...);
//or:
bool b[] = {(some_function(args),true)...};
}
因为在第一种情况下,您没有逗号分隔的参数,而是使用逗号操作符,这是完全不同的东西。
你可以递归地实现expand
函数:
inline void expand() {}
template<typename T, typename... Args>
inline void expand(T&& head, Args&&... tail)
{
some_function(head);
expand(tail...);
}
一个直截了当的答案是,这不是一个标准允许包扩展的环境。允许的上下文的完整列表在14.5.3/4:
中指定4一个包展开由一个图案和一个省略号组成类的实例化产生零个或多个实例化列表中的模式(如下所述)。模式的形式取决于关于扩展发生的上下文。包扩展可以出现在以下上下文中:
-在函数参数包中(8.3.5);模式是不带省略号的参数声明。
-在模板参数pack中,它是一个包扩展(14.1):
如果模板参数包是参数声明;的pattern是没有省略号的参数声明;
如果模板参数包是带template-parameter-list;模式是相应的
-在初始化列表中(8.5);模式是一个初始化子句。
-在基本说明符列表中(条款10);模式是一个基本说明符。
-在mem-initializer-list中(12.6.2);模式是mem-initializer .
-在template-argument-list中(14.3);模式是模板参数。
-在动态异常规范中(15.4);模式是id类型。
-在属性列表中(7.6.1);模式是一个属性。
-在对齐说明符(7.6.2)中;模式是不带省略号的对齐说明符。
-在捕获列表(5.1.2)中;模式是一个捕获。
-尺寸为…表达式(5.3.3);模式是一个标识符。
下面是一种可能的解决方法,可以保证参数按照从左到右的顺序求值:
struct expand_aux {
template<typename... Args> expand_aux(Args&&...) { }
};
template<typename... Args>
inline void expand(Args&&... args)
{
expand_aux temp { some_function(std::forward<Args>(args))... };
}
- (C++)分析树以计算返回错误值的简单算术表达式
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 如何将 txt 文件中的行分隔为组件C++
- 无法通过空白将文本文件行分隔为矢量
- 提升精神:解析布尔表达式并简化为规范范式
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 使用正则表达式regex_search在字符串中查找字符串
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 概念中的cv限定符需要表达式参数列表
- 为什么constexpr的性能比正常表达式差
- 对于结构,表达式必须是可修改的ivalue
- 如何在C++中读取空格分隔的输入 当我们不知道输入的数量时
- C ++正则表达式允许用点分隔的数字
- 以逗号分隔的表达式中的析构函数调用
- 使用 STD 正则表达式标记逗号分隔的列表
- 逗号分隔的正则表达式,除非逗号在括号内
- 使用boost正则表达式提取所有以短划线分隔的数字
- 匹配以空格分隔的多个坐标的正则表达式
- c++ 11可变模板和逗号分隔表达式的等价性
- c++标准算法,用最低优先级的运算符分隔一个表达式为两个表达式