将非const引用传递给C ++中的右值

将非const引用传递给C ++中的右值

问题描述:

在下面的代码中:

bootrec_reset(File(path, size, off), blksize);

使用原型调用函数:

static void bootrec_reset(File &file, ssize_t blksize);

我收到此错误:


libcpfs / mkfs.cc:99:53:错误:从类型为'File'的右值初始化类型为'File&'的非const引用

libcpfs/mkfs.cc:99:53: error: invalid initialization of non-const reference of type 'File&' from an rvalue of type 'File'

libcpfs / mkfs.cc:30:13:错误:传递了'void bootrec_reset(File& ssize_t)'

libcpfs/mkfs.cc:30:13: error: in passing argument 1 of 'void bootrec_reset(File&, ssize_t)'

我知道你不能根据标准传递非const引用( const& )到右值。然而,MSVC允许您这样做(请参阅此问题)。 此问题尝试解释为什么,但答案没有意义,因为他使用引用字面量,

I'm aware that you can not pass non-const references (const &) to rvalues according to the standard. MSVC however allows you to do this (see this question). This question attempts to explain why but the answer makes no sense as he is using references to literals, which are a corner case and should obviously be disallowed.

在给定的例子中,我们可以清楚地看到事件的顺序将会发生(就像在MSVC中一样):

In the given example it's clear to see that following order of events will occur (as it does in MSVC):


  1. 文件的构造函数将被调用。

  2. 文件 blksize 的引用被推入堆栈。

  3. bootrec_reset 使用文件

  4. bootrec_reset ,临时文件被销毁。

  1. File's constructor will be called.
  2. A reference to the File, and blksize, are pushed on the stack.
  3. bootrec_reset makes use of file.
  4. After returning from bootrec_reset, the temporary File is destroyed.

需要指出的是, File 引用需要是非const,因为它是一个文件的临时句柄, const方法被调用。此外,我不想把 File 的构造函数参数传递给 bootrec_reset 看到任何原因手动构造和销毁调用者中的文件对象。

It's necessary to point out that the File reference needs to be non-const, as it's a temporary handle to a file, on which non-const methods are invoked. Furthermore I don't want to pass the File's constructor arguments to bootrec_reset to be constructed there, nor do I see any reason to manually construct and destroy a File object in the caller.

所以我的问题是: p>

So my questions are:


  1. 以这种方式禁止非const引用的C ++标准是什么?

  2. 如何强制GCC允许这个代码?

  3. 即将到来的C ++ 0x标准会改变这一点,或者有新的标准给我的东西,这里更适合,例如所有的乱七八糟的rvalue references?


是的,plain函数不能绑定非const引用暂时 - 但方法可以 - 总是欺骗我。 TTBOMK的原理是这样的(源自这个comp。 lang.c ++。moderated thread ):

Yes, the fact that plain functions cannot bind non-const references to temporaries -- but methods can -- has always bugged me. TTBOMK the rationale goes something like this (sourced from this comp.lang.c++.moderated thread):

假设你有:

 void inc( long &x ) { ++x; }

 void test() {
     int y = 0;
     inc( y );
     std::cout << y;
 } 



如果您允许 long& x 参数 inc()绑定到从 long > y ,这个代码显然不会做你期望的 - 编译器只是静静地产生让 y 不变的代码。显然,这是早期C ++日常见的错误来源。

If you allowed the long &x parameter of inc() to bind to a temporary long copy made from y, this code obviously wouldn't do what you expect -- the compiler would just silently produce code that leaves y unchanged. Apparently this was a common source of bugs in the early C++ days.

如果我设计C ++,我的偏好是允许非const引用绑定到临时,但禁止在绑定到引用时从左值到临时值的自动转换。但是谁知道,那可能会打开一个不同的蠕虫...

Had I designed C++, my preference would have been to allow non-const references to bind to temporaries, but to forbid automatic conversions from lvalues to temporaries when binding to references. But who knows, that might well have opened up a different can of worms...