完美转发不适用于C ++

时间:2016-11-27 17:12:00

标签: c++

我试图理解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

1 个答案:

答案 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_Classtemplate<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; ...