10

在 Visual Studio 2012RC 中有一些非标准扩展。例如这段代码编译:

#include <string>

using namespace std;

void value(string& value)
{
    value = "some";
}

int main()
{
    value(string("nice"));
}

并警告它是非标准扩展。所以,我想了解它是如何真实的以及代码如何转换(右值引用或带有 const_cast 的 const 引用)?

4

3 回答 3

8

类类型的临时对象仍然是对象。它存在于内存中的某个地方,这意味着编译器能够附加对它的引用并没有什么不寻常的地方。在物理层面上,它是常量引用还是非常量引用都没有区别。换句话说,在这种情况下,语言限制纯粹是概念性的、人为的。编译器只是忽略了这个限制。这里没有必要“转换”任何东西。引用只是直接附加到对象上,无论该对象恰好位于何处。

基本上,对于一个为外部词提供访问其this指针值(或左值访问*this)的类,可以立即轻松地模拟行为

struct S {
  S& get_lvalue() { return *this; }
};

void foo(S& s);
...

foo(S().get_lvalue());

上面的代码是完全合法的,它可以绕过上述限制。您可以将 MSVC++ 行为视为与此等价。

于 2012-07-16T16:47:44.010 回答
3

基本上,VS 会在某处分配空间并让引用指向它,就好像它是一个const没有常量的引用(或者在 C++11 中是一个右值引用)。

/Za您可以使用下面的(禁用语言扩展)编译器开关禁用此行为

属性 -> C/C++ -> 语言

如果我没记错的话。

于 2012-07-16T16:42:19.570 回答
3

在标准 C++ 中,您不能将临时 (rvalue / string("nice")) 绑定到非常量引用 (lvalue),但 microsoft 编译器允许这样做。警告告诉您代码由于扩展而正在编译,并且不会与任何其他编译器一起编译。

于 2012-07-16T16:42:22.653 回答