C++ 系数模板参数包操作
在下面的模板函数定义中,我编写了两次相对较长的表达式C++ 系数模板参数包操作,c++,variadic-templates,c++17,C++,Variadic Templates,C++17,在下面的模板函数定义中,我编写了两次相对较长的表达式details::transform(std::forward(t)),其中t是一个参数包 我怎样才能考虑它 auto-pack=details::transform(std::forward(t))当然不起作用 template<class ...T> void f(T&&... t) { auto check = (details::transform(std::forward<T>(t))
details::transform(std::forward(t))
,其中t
是一个参数包
我怎样才能考虑它
auto-pack=details::transform(std::forward(t))
当然不起作用
template<class ...T>
void f(T&&... t)
{
auto check = (details::transform(std::forward<T>(t)) && ...);
if (check == false) {
return;
}
details::act(details::transform(std::forward<T>(t))...);
}
模板
无效f(T&…T)
{
自动检查=(详细信息::转换(std::转发(t))&&&;
如果(检查==false){
返回;
}
细节::act(细节::转换(std::转发(t))…);
}
出于测试目的,这里有一个。您可以使用宏
#define FORWARD_TRANSFORM(type, var) details::transform(std::forward<type>(var))
#定义前向#转换(类型,变量)详细信息::转换(标准::前向(变量))
然后你的函数就变成了
template<class ...T>
void f(T&&... t)
{
auto check = (FORWARD_TRANSFORM(T, t) && ...);
if (check == false) {
return;
}
details::act(FORWARD_TRANSFORM(T, t)...);
}
模板
无效f(T&…T)
{
自动检查=(前向_变换(T,T)&&…);
如果(检查==false){
返回;
}
细节::act(前向_变换(T,T)…);
}
< C++ >有一个悲哀的事实。转发可以成为令牌集群。需要转发的表达越复杂,就越痛苦
可悲的是,我所知道的减轻它的唯一方法是使用预处理器
#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
#定义前向(…)标准::前向(uu VA_uargs_uu)
有了它,我们可以重构您的函数,使用IILE只生成一次包:
template<class ...T>
void f(T&&... t)
{
[](auto&&... pack) {
auto check = (FWD(pack) && ...);
if (check == false) {
return;
}
details::act(FWD(pack)...);
}(details::transform(FWD(t))...);
}
模板
无效f(T&…T)
{
[](自动和…打包){
自动检查=(FWD(包装)和&…);
如果(检查==false){
返回;
}
详细信息:act(FWD(包装);
}(细节:变换(FWD(t))…);
}
这样,每个参数只调用一次transform
。我想这就是我们的净目标。否则,您可能可以使用预处理器在没有lambda的情况下生成更简单的内容。您不能这样做。您的两个变量表达式扩展为不同的模式。您所能做的最好的事情是这样(没有宏):
模板
无效f(T&…T)
{
使用细节::转换;
//(T&&)T==std::forward(T);
自动检查=(转换((T&&)T&&…);
如果(检查==false){
返回;
}
细节::act(转换((T&&)T);
}
我的意思是,如果要使用宏,为什么不使用#define expr details::transform(std::forward(t))代码>:PIILE:立即调用lambda expressio。
template<class ...T>
void f(T&&... t)
{
using details::transform;
// (T&&)t == std::forward<T>(t);
auto check = (transform((T&&)t) && ...);
if (check == false) {
return;
}
details::act(transform((T&&)t)...);
}