简体   繁体   English

为什么 std::forward 将我的左值变成右值?

[英]Why is std::forward turning my lvalue into an rvalue?

template<class T>
struct IntHolder {
    T i;
};

template<class T>
void addOne(T& t) {
    t.i += 1;
}

template<class... Args>
void addAll(Args... args) {
      // Magic to run addOne on each arg
      int dummy[] = { 0, ((void)addOne(std::forward<Args>(args)), 0)... };
}

int main() {
    IntHolder<int> x{2};
    IntHolder<double> t{3};
    addAll(x, t);
    return 0;
}

This toy example won't compile because这个玩具示例无法编译,因为

prog.cc: In instantiation of 'void addAll(Args ...) [with Args = {IntHolder<int>, IntHolder<double>}]':
prog.cc:60:16:   required from here
prog.cc:54:39: error: invalid initialization of non-const reference of type 'IntHolder<int>&' from an rvalue of type 'IntHolder<int>'
       int dummy[] = { 0, ((void)addOne(std::forward<Args>(args)), 0)... };
                                       ^
prog.cc:48:6: note:   initializing argument 1 of 'void addOne(T&) [with T = IntHolder<int>]'
 void addOne(T& t) {

What I thought would happen here is that addAll gets two lvalues passed in, and then addOne would be called on each of those as an lvalue.我认为这里会发生的是 addAll 获取两个传入的左值,然后 addOne 将在每个左值上被调用。 However, it seems somewhere along the way, the compiler thinks that the argument is getting converted to an rvalue.但是,似乎在某个地方,编译器认为参数正在转换为右值。 Why might this be?为什么会这样?

You're declaring parameter as non-reference, ie pass-by-value, then when being passed x and t , the type would be deduced as IntHolder<int> and IntHolder<double> .您将参数声明为非引用,即按值传递,然后在传递xt时,类型将被推断为IntHolder<int>IntHolder<double> Then std::forward<Args> would convert them into rvalues.然后std::forward<Args>会将它们转换为右值。

For forwarding reference it should be对于转发参考,它应该是

template<class... Args>
void addAll(Args&&... args) {
    //          ^^
    // Args would be deduced as IntHolder<int>&, IntHolder<double>&
    // then std::forward<Args>(args) yields lvalues 
    int dummy[] = { 0, ((void)addOne(std::forward<Args>(args)), 0)... };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM