为什么不允许获得对一个临时对象的非常量引用,getx()返回哪个函数?显然,这是C++标准所禁止的
但是我对这种限制的目的很感兴趣,不是对该标准的引用。

struct X
{
    X& ref() { return *this; }
};

X getx() { return X();}

void g(X & x) {}

int f()
{
    const X& x = getx(); // OK
    X& x = getx(); // error
    X& x = getx().ref(); // OK
    g(getx()); //error
    g(getx().ref()); //OK
    return 0;
}
  • 很明显,对象的生存期不能成为原因,因为
    C++标准不禁止对对象的常量引用。
  • 很明显,上面的示例中的临时对象不是常量,因为允许调用非常量函数。例如,ref()可以修改临时对象。
  • 此外,ref()允许您欺骗编译器并获得指向该临时对象的链接,从而解决了我们的问题。

  • 另外:

    他们说“将临时对象分配给const引用可延长该对象的生命周期”,“关于非const引用却一无所获”。
    我的附加问题。以下分配是否会延长临时对象的生命周期?
    X& x = getx().ref(); // OK
    

    最佳答案

    从这个Visual C++ blog article about rvalue references:



    基本上,您不应该因为临时对象是临时对象并且会在任何时候死掉的原因而尝试修改它们。允许您调用非const方法的原因是,只要您知道自己在做什么并且对它很明确,就可以做一些“愚蠢”的事情(例如,使用reinterpret_cast)。但是,如果将一个临时对象绑定(bind)到一个非const引用,则可以继续将其永久传递给“永久”对象,以使对对象的操作消失,因为在整个过程中您完全忘记了这是一个临时对象。

    如果我是你,我会重新考虑我的功能设计。为什么g()接受引用,它会修改参数吗?如果不是,请使其成为const引用,如果是,请为什么尝试将临时变量传递给它,您是否不在乎它是您要修改的临时变量?为什么getx()无论如何都会返回临时值?如果您与我们分享您的真实情况以及您想要实现的目标,则可能会得到一些很好的建议。

    违反语言并欺骗编译器很少解决问题-通常会产生问题。

    编辑:解决评论中的问题:
    1)X& x = getx().ref(); // OK when will x die?-我不知道,我也不在乎,因为这正是我“违背语言”的意思。该语言表示:“除非声明绑定(bind)到const引用,否则临时语句会在语句末尾消失,在这种情况下,当引用超出范围时它们就会死亡”。应用该规则,似乎x在下一条语句的开头已经死了,因为它没有绑定(bind)到const引用(编译器不知道ref()返回什么)。但是,这只是一个猜测。

    2)我清楚地说明了目的:不允许修改临时对象,因为这样做没有意义(忽略C++ 0x rvalue引用)。问题“那为什么允许我打电话给非const成员?”是一个不错的选择,但是我没有比我上面已经说过的更好的答案了。

    3)好吧,如果我对语句末尾的X& x = getx().ref();中的x没错,那么问题就显而易见了。

    无论如何,根据您的问题和评论,我认为即使这些额外的答案也无法满足您。这是最后的尝试/摘要:C++委员会认为修改临时文件没有意义,因此,它们不允许绑定(bind)到非const引用。我不知道,可能是某些编译器实现或涉及历史性问题。然后,出现了一些特定情况,并决定在各种情况下,它们仍然允许通过调用非常量方法直接进行修改。但这是一个异常(exception)-通常不允许您修改临时文件。是的,C++通常很奇怪。

    关于c++ - 非常量引用为什么不能绑定(bind)到临时对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1565600/

    10-11 22:31
    查看更多