【问题标题】:Is there a way to disable binding a temporary to a const reference?有没有办法禁用将临时绑定到 const 引用?
【发布时间】:2012-12-11 15:55:47
【问题描述】:

在 C++ 中,可以将临时对象绑定到 const 引用:

struct A {};

int main() {
  const A& a = A();
}

有什么方法可以为某些特定的 A 类禁用此功能,从而无法将此类的临时绑定到 const 引用?

【问题讨论】:

  • 只是出于好奇,你为什么要这么做?
  • 我不需要那个,只是出于好奇问=)
  • 这个例子很傻,但你可能想直接将引用绑定到某个对象,即使引用是 const。
  • 隐藏在将const & 绑定到右值的机制背后的蠕虫罐头(终身延长)在此处进行了更详细的讨论:quuxplusone.github.io/blog/2020/03/04/rvalue-lifetime-disaster

标签: c++ reference object-lifetime


【解决方案1】:

不,如果你需要这样做,那你就做错了。

【讨论】:

  • 实际上根据 C++03 有一种方法可以做到这一点,但它不适用于流行的编译器。详情见我的回答。
【解决方案2】:

一般来说,似乎没有办法禁用将临时对象绑定到 const 引用。

但是,为了给出一个有根据的答案,我想引用 C++ 2003 标准:

如果初始化表达式是一个右值,T2 是一个类类型,并且“cv1 T1”是引用兼容的 对于“cv2 T2”,引用以下列方式之一绑定(选择由实现定义):

——引用绑定到右值表示的对象(见 3.10)或其中的子对象 那个对象。

——创建一个“cv1 T2”[原文如此]类型的临时对象,并调用构造函数来复制整个 右值对象到临时。引用绑定到临时对象或子对象 临时之内。 93)

无论复制是否实际完成,用于制作复制的构造函数都应该是可调用的。

因此,在 C++03 中,这似乎可以通过将复制构造函数设为私有来实现:

struct A {
  A() {}
 private:
  A(const A&);
};

int main() {
  const A& a = A();
}

但是,这不适用于流行的编译器。例如,即使带有-std=c++03 标志,GCC 也接受上述代码。 Clang 也接受此代码,但带有警告:

test.cc:8:12: 警告:C++98 需要类“A”的可访问复制构造函数 将引用绑定到临时对象时;是私人的

因此与标准相反,没有办法做到这一点。

在这种情况下,C++11 不再需要可访问的复制构造函数。

【讨论】:

    猜你喜欢
    • 2019-07-02
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 2013-07-04
    • 1970-01-01
    • 2019-12-25
    • 2011-01-21
    相关资源
    最近更新 更多