在以下模板函数定义中,我写了两倍的相对长的表达式details::transform(std::forward<T>(t))
,其中t
是一个参数包。
我该如何考虑呢?
auto pack = details::transform(std::forward<T>(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))...);
}
出于测试目的,这里是complete program on coliru。
答案 0 :(得分:4)
您可以使用宏。
#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)...);
}
答案 1 :(得分:4)
C ++有一个可悲的事实。转发可以成为令牌的集群。需要转发事物的表达越复杂,它就会变得越痛苦。
可悲的是,我唯一知道的缓解方法是使用预处理器...
#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
有了这些,我们可以重构您的函数,使其仅使用一次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))...);
}
这样,每个参数只调用一次transform
。我认为这是最终目标。否则,您可能可以使用预处理器来生成更简单的东西,而无需使用lambda。
答案 2 :(得分:1)
您不能那样做。您的两个可变参数表达式扩展为不同的模式。您能做的最好的事情就是这样(没有宏):
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)...);
}