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 将作为左值在每个左值上调用。但是,似乎在此过程中的某个地方,编译器认为参数正在转换为右值。为什么会这样?
答案 0 :(得分:6)
您将参数声明为非引用,即按值传递,然后在传递 x
和 t
时,类型将推导出为 IntHolder<int>
和 {{ 1}}。然后 IntHolder<double>
会将它们转换为右值。
对于 forwarding reference 应该是
std::forward<Args>