C++ 为什么在未赋值的操作数中进行包扩展会导致最后一个元素?
我可以在C++ 为什么在未赋值的操作数中进行包扩展会导致最后一个元素?,c++,templates,c++11,variadic-templates,comma-operator,C++,Templates,C++11,Variadic Templates,Comma Operator,我可以在decltype()中执行此操作: auto g()->decltype(1,”,true,新int); 但不是这个: 模板 自动g(Args&&…Args)->decltype(Args; 它失败是因为包扩展出现在decltype()中,但我认为包扩展会导致参数列表以逗号分隔。因此g(a,b,c)的返回类型将是decltype(c),因为逗号运算符是如何工作的(它返回最后一个元素)。当您在函数参数列表、模板参数列表、初始值设定项列表等内部展开时,它会起作用。但为什么不是这样呢?参数
decltype()中执行此操作:
auto g()->decltype(1,”,true,新int);
但不是这个:
模板
自动g(Args&&…Args)->decltype(Args;
它失败是因为包扩展出现在decltype()
中,但我认为包扩展会导致参数列表以逗号分隔。因此g(a,b,c)
的返回类型将是decltype(c)
,因为逗号运算符是如何工作的(它返回最后一个元素)。当您在函数参数列表、模板参数列表、初始值设定项列表等内部展开时,它会起作用。但为什么不是这样呢?参数包仅在某些情况下展开。您可以通过搜索“包扩展”在标准中找到它们。比如说,
功能参数包是包扩展(14.5.3)
(8.3.5/14)
除非在某个地方明确指定包扩展发生在特定上下文中,否则它不会发生,并且通常被语法禁止(即语法不正确)。例如,decltype
需要一个表达式作为其操作数1,“,true,new int
确实是一个表达式(,
是逗号运算符),但args…
不是一个表达式。但是,args…
是一个表达式列表,因此可以使用它,例如在函数调用中。逗号运算符与逗号表达式分隔符不同
逗号运算符接受两个表达式,计算左侧,丢弃它,计算右侧,然后返回结果
当您有表达式列表(如函数调用或初始值设定项列表)时,将使用表达式分隔符
decltype(a,b,c)
是decltype(
expression)
,而不是decltype(
expression list)
)。这意味着decltype
中的,
是运算符逗号
通常,…
扩展仅在语法允许表达式列表时才起作用。,
“generated”是表达式分隔符,而不是逗号运算符
我不知道有什么方法可以使用…
模拟,
操作符的行为,包括执行顺序。如果您不关心它们的评估顺序,可以执行以下操作:
template<class T, class... Ts>
struct last_type_helper{using type=T;};
template<class T0, class T1, class... Ts>
struct last_type_helper<T0, T1, Ts...>:last_type_helper<T1, Ts...>{}
template<class... Ts>
using last_type=typename last_type_helper<Ts...>::type;
template<class T0>
T0&& last_expression( T0&& t0 ) { return std::forward<T0>(t0); }
template<class T0, class...Ts>
auto last_expression( T0&& t0, Ts&&...ts )->last_type<T0, Ts...>&& {
return last_expression( std::forward<Ts>(ts)... );
}
模板
结构last_type_helper{using type=T;};
模板
结构last_type_helper:last_type_helper{}
模板
使用last\u type=typename last\u type\u helper::type;
模板
T0&&last_表达式(T0&&T0){return std::forward(T0);}
模板
自动最后一个表达式(T0&&T0,Ts&&Ts)->最后一个类型&&{
返回最后一个_表达式(std::forward(ts)…);
}
然后
模板
自动g(Args&&…Args)->decltype(最后一个表达式(Args…);
工作也一样
template<class...Args>
auto g(Args&&...args) -> last_type<Args...>;
模板
自动g(Args&&…Args)->最后一种类型;
这是本末倒置,不是吗?我有理由相信这不是它的工作原理。包扩展永远不会给你一个带有逗号分隔符的表达式。它根据上下文为您提供不同的列表“根据展开的位置,生成的逗号分隔列表是不同类型的列表:函数参数列表、成员初始值设定项列表、属性列表等。”
。但它永远不会给您一个带有逗号运算符的表达式。它不像宏那样只是文本替换。
template<class...Args>
auto g(Args&&...args) -> last_type<Args...>;