-2

我很想知道为什么&a = &bC++ 中不允许这样的赋值。

我理解这样做的风险,但至少对我来说,这不是完全禁止它的充分理由。我之所以这么想是因为我正在寻找一种无需复制即可交换大对象的智能方法,而类似的方法似乎是个好主意:

void ptr_swap( ptrdiff_t &a, ptrdiff_t &b )
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}

int main()
{
    double a = 157648.13;
    double b = 96871.84;

    printf("%.4f %.4f\n", a, b);

    ptr_swap( reinterpret_cast<ptrdiff_t>(&a), reinterpret_cast<ptrdiff_t>(&b) );

    printf("%.4f %.4f\n", a, b);
}

..但显然,编译器不这么认为。:(

编辑:我明白为什么这不起作用。也许我的问题会这样更清楚:我不知道一个变量在程序中有多少属性,但至少有一个名称、一个值、一个地址,也许还有一些关于它生命周期的指示。对我来说,交换本质上是重命名存储在内存中的两个现有值,而且它会产生副本是无稽之谈。

有了我放弃的这个“可怕”的代码示例,我想做的是对编译器说:“从现在开始,b 被命名为 a,反之亦然”。为什么这样的事情是不可能的?动机是已经有可能以某种方式“指导编译器”,例如通过 TMP,那么为什么不这样做呢?

4

5 回答 5

9

在我看来,您想更改对象的地址,对吗?那是不可能的。每个对象在其整个生命周期中都有一个固定的地址。你永远不能给一个对象一个不同的地址。对象的地址隐含在生成的机器代码中,它本身并不存储在任何地方。

于 2012-12-05T19:40:06.000 回答
3

&是一个以值作为结果的运算符。你会如何给某个值赋值?例子:

int i, n;
i + n = 50;
于 2012-12-05T19:28:18.500 回答
2

从问题的顶部开始:

Why are pointers obtained by the address-of operator not lvalues?

根据c99标准,

ISO : c99 6.5.3.2 Address and indirection operators

语义

3
The unary & operator yields the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the **result is not an lvalue**.

临时性是对象的属性。当您创建对象的引用时,它只是临时的,您不能为其他变量重新定义相同的引用。

现在,在您的情况下,您所做的passing by address不是passing by reference. 因为只需要传递变量,所以在调用环境中pass by reference不需要。&

只需这样做:

 swap(a,b); // calling

void swap(int &a, int &b)
{
 // definition 
 // here a and b are reference.
}
于 2012-12-05T19:32:22.217 回答
2

已经有很多其他的方法可以做到这一点,为什么还要再有一种不如其他的呢?您可以使用智能指针完美地做到这一点。

于 2012-12-05T19:32:26.833 回答
1

对象是内存中的一个位置。
变量名是对象的引用(在程序中引用对象的一种方式)。但并非所有变量都有名称。

但是你可以通过将别名传递给你的变量来实现你想要的:

void print(double& ref1, double& ref2)
{
    printf("%.4f %.4f\n", ref1, ref2);
}
int main()
{
    double a = 157648.13;
    double b = 96871.84;

    print(a, b);    
    print(b, a); // Pass them the function the other way around.
                 // You have effectively swapped the values (as far as the function is concerned).
}

在我的选择中,您正在尝试解决一个不存在的问题。

于 2012-12-05T21:42:06.110 回答