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

时间:2021-05-04 00:32:51

标签: c++ c++11

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;
}

这个玩具示例无法编译,因为

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) {

我认为这里会发生的是 addAll 传入两个左值,然后 addOne 将作为左值在每个左值上调用。但是,似乎在此过程中的某个地方,编译器认为参数正在转换为右值。为什么会这样?

1 个答案:

答案 0 :(得分:6)

您将参数声明为非引用,即按值传递,然后在传递 xt 时,类型将推导出为 IntHolder<int> 和 {{ 1}}。然后 IntHolder<double> 会将它们转换为右值。

对于 forwarding reference 应该是

std::forward<Args>