我试图理解C ++中的转发概念,并编写下面的代码来理解可变参数模板上的这个功能。
#include<utility>
#include<string>
#include<tuple>
#include<sstream>
template<typename... Args> struct Helper_Class
{
std::tuple<Args...> argTuple;
Helper_Class(Args&&... args):
argTuple(std::make_tuple(std::forward<Args>(args)...))
{}
};
template<typename... Args> std::ostream&
operator<< ( std::ostream& os,Helper_Class<Args...> obj)
{
return os;
}
template<typename...Args>
Helper_Class< Args...>
Print(Args&&... args)
{
return Helper_Class<Args...>(std::forward<Args>(args)...);
}
template <typename... Ts>
void test( Ts &&...params) {
std::stringstream s;
s <<Print(std::forward<Ts>(params)...);
}
int main()
{
test(1,2,"foo", 'x');
}
然而,在执行代码时我遇到了错误:
error: no matching function for call to ‘std::tuple<int, int, const char (&)[4], char>::tuple(std::tuple<int, int, const char*, char>)’
argTuple(std::make_tuple(std::forward<Args>(args)...))
我不理解的是,如果我试图进行完美的转发(意味着类型不应该在函数调用之间改变)为什么要尝试更改类型?
请原谅这是非常基本的,因为我第一次学习这个概念。
更新1: 问题发布在Question
上答案 0 :(得分:5)
template <typename... Ts>
void test( Ts &&...params) {
std::stringstream s;
s <<Print(std::forward<Ts>(params)...);
}
你将从这里开始。 Print
的模板参数将来自std::forward
。因此,他们已经转发了左值/右值参考等。这就是您要推送的内容,作为Print
模板的参数。
然后:
template<typename...Args>
Helper_Class< Args...>
Print(Args&&... args)
现在将Args...
转发给Helper_Class
,template<typename...Args>
Helper_Class< typename std::decay<Args>::type...>
Print(Args&&... args)
{
return Helper_Class<typename std::decay<Args>::type...>(std::forward<Args>(args)...);
}
将使用这些类型来尝试声明包含左值引用,右值引用等的元组。这不会很好。
你need to decay这些吸盘:
template<typename...Args>
auto Print(Args&&... args)
{
return Helper_Class<typename std::decay<Args>::type...>(std::forward<Args>(args)...);
}
或者,让我们使用C ++ 14来清理一些视觉混乱......
i1 <- with(df, as.logical(ave(year, ID, FUN = function(x) {
i1 <- (x[-1] - x[-length(x)]) ==1
i2 <- c(FALSE, i1)
i3 <- c(i1, FALSE)
rl <- rle(i2|i3)
rl$values[rl$values][rl$lengths[rl$values] <5] <- FALSE
rep(rl$values, rl$lengths)
})))
df[i1,]
# ID year
#10 A 1984
#11 A 1985
#12 A 1986
#13 A 1987
#14 A 1988
#15 A 1990
#16 A 1991
#17 A 1992
#18 A 1993
#19 A 1994
#20 A 1995
现在为我编译,使用gcc 6.2.1。
P.S。这不完全是&#34;基本&#34; ...