为什么f(x).swap(v)没问题,但v.swap(f(x))不是?

时间:2010-11-05 05:49:25

标签: c++

我们有:

vector<int> f(int);

vector<int> v;

这有效:

f(x).swap(v);

这不是:

v.swap(f(x));

为什么?

3 个答案:

答案 0 :(得分:7)

swap()vector<int>采用非const引用。非const引用不能绑定到rvalue(临时对象)。对按函数返回的函数的调用(如f)是一个右值。

f(x).swap(v)的工作原因是因为std::vector<int>::swap内部f(x)返回的临时对象可以使用this来引用自身。 this不是右值。

答案 1 :(得分:1)

您可以在temporaries上调用成员函数,但在C ++中,它们不能绑定到非const引用。

例如:

int &x = 5; // illegal because temporary int(5) cannot be bound to non-const reference x

答案 2 :(得分:1)

实际上,(虽然James' answer肯定是正确的(Prasoon's也是如此),但仍有一些潜在的问题需要掌握。

当我们将f(x)缩减为其结果yy.swap(v)(或v.swap(y)时,在这种情况下无关紧要)使用通用标识符名称,它变成

y.func(v)

现在,func()是一个带有一个参数的成员函数,它实际上有 两个参数 :传递的内容为v,并且 每个非静态成员函数接收的隐式this指针 ,此处绑定到y。抛弃封装,可以将称为y.func(v)的每个成员函数设置为非成员函数,以便将其称为func(y,v)。 (实际上,实际上非成员swap()函数。此外,每次需要重载其中一个二进制运算符时,这些运算符可能会作为成员或非成员重载,你必须做出这个决定。)

然而,y.func(v)func(y,v)之间存在细微的差别,因为C ++会处理this参数,即通过在.之前写入它来传递的参数(点),与其他论点不同,它在很多方面都是如此 正如您所发现的,即使对于非this成员函数,const参数也可能是rvalue(临时),而对于其他参数, 非const引用会阻止< / em> rvalues被绑定到参数。此外,this参数的 运行时类型可能会影响调用哪个函数 (对于virtual成员),而其他参数'run-时间类型是无关紧要的,因为仅根据编译时类型选择函数。隐式转换只会应用于成员函数的显式参数,但永远不会应用于其隐式this参数。 (这就是为什么你可以传递const std::string&的字符串文字,但不能在字符串文字上调用std::string::size()。)

因此,总而言之,尽管.之前的内容最终是一个(隐含的)函数参数,但实际上 处理方式与 非常不同 其他函数参数。