将临时绑定到左值引用

Posted

技术标签:

【中文标题】将临时绑定到左值引用【英文标题】:Binding temporary to a lvalue reference 【发布时间】:2009-08-28 06:42:15 【问题描述】:

我有以下代码

string three()

    return "three";


void mutate(string& ref)



int main()

    mutate(three()); 
    return 0;

你可以看到我正在将 three() 传递给 mutate 方法。这段代码编译得很好。我的理解是,不能将临时对象分配给非常量引用。如果是,这个程序是如何编译的?

有什么想法吗?

编辑:

尝试过的编译器:VS 2008 和 VS2010 Beta

【问题讨论】:

试试 GCC,它更接近 C++ 标准。 很遗憾,我没有 GCC。 @Appu:在我修复了缺少包含和 std 前缀的代码后,Comeau (comeaucomputing.com/tryitout) 说:initial value of reference to non-const must be an lvalue。 VC接受这个的原因是因为VC坏了。 (他们称其为“功能”,但实际上它是一个错误。) 【参考方案1】:

它曾经在 VC6 编译器中编译,所以我想为了保持向后兼容性 VS2008 支持这个非标准扩展。尝试使用/Za(禁用语言扩展)标志,你应该会得到一个错误。

【讨论】:

指定/Za 选项可能会导致包含windows.h 或其他Windows 特定标题的问题。 使用警告级别为四是我使用的更好的选择【参考方案2】:

这是 VC++ 的邪恶扩展。如果您使用 /W4 进行 oompile,那么编译器会警告您。我猜你正在阅读Rvalue References: C++0x Features in VC10, Part 2。这篇文章也提到了这个问题。

【讨论】:

【参考方案3】:

这是一个 Microsoft 扩展,用于模仿许多其他 Microsoft 编译器的行为。如果启用 W4 警告,您将看到警告。

【讨论】:

【参考方案4】:

编译,至少使用 g++ 4:

foo.cpp: In function ‘int main()’:
foo.cpp:16: error: invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type ‘std::string’
foo.cpp:10: error: in passing argument 1 of ‘void mutate(std::string&)’

(行号相差 3 或 4,因为我必须添加 #include 和 'using' 行。)

因此,您的编译器似乎没有应有的严格。

【讨论】:

编辑了帖子并添加了我正在使用的编译器。【参考方案5】:

我猜这取决于编译器。 g++ 4.1.2 给了我这个。

In function 'int main()':
Line 15: error: invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'std::string'
compilation terminated due to -Wfatal-errors.

也许是因为你没有做任何事情,所以调用被优化掉了。

【讨论】:

我尝试用 mutate() 方法中的 ref 参数做一些事情,它仍然可以编译 我刚刚在 VC++ 中尝试过,它可以编译并工作,除非您在项目属性中禁用扩展。当您这样做时: 1>main.cpp 1>d:\all\projects\laptop\2\asd\asd\main.cpp(16) : error C2664: 'mutate' : cannot convert parameter 1 from 'std ::string' 到 'std::string &' 1> 非常量引用只能绑定到左值

以上是关于将临时绑定到左值引用的主要内容,如果未能解决你的问题,请参考以下文章

13.6对象移动

对临时声明的右值引用

error C2662 无法将左值绑定到右值 —— 变量永远是左值,即使它的类型为右值引用

右值引用,移动语义,完美转发

[c++11]右值引用移动语义和完美转发

c ++使用临时对象右值初始化左值引用以及自动推导[重复]