猿问

一个VS2010错误?允许将非常量引用绑定到右值而没有警告?

string foo() { return "hello"; }

int main() 

{

    //below should be illegal for binding a non-const (lvalue) reference to a rvalue

    string& tem  = foo();   


    //below should be the correct one as only const reference can be bind to rvalue(most important const)

    const string& constTem = foo();   

}

GCC是产生编译错误的好方法:std::string&从类型的临时类型对类型的非常量引用进行无效的初始化std::string

VS2008还不错,至少它给出了编译警告:警告C4239:使用了非标准扩展名:'initializing':从转换std::string为std::string &非常量引用只能绑定到左值

这是有问题的一个-VS2010(SP1)可以很好地编译,没有任何错误或警告,为什么??!我知道VS2010中的右值引用可用于与右值绑定,但是我没有使用&&,而是在演示代码中,我只是在使用非常量左值引用!

somone可以在这里帮助我解释VS2010的行为吗?这是一个错误!谢谢


呼如林
浏览 992回答 3
3回答

交互式爱情

这是VS编译器的已知问题/功能。他们一直允许这样做,并且似乎没有任何推动力去删除该扩展名。

噜噜哒

编译器将在启用“禁用语言扩展”的情况下发出错误,并在/ W4处发出警告。但是,删除此代码将破坏以前的编译代码,Microsoft非常不愿意这样做。这也是为什么他们不会修复其SFINAE支持的原因。

潇潇雨雨

几年后以及许多版本的Visual Studio之后,我们仍然遇到这种“扩展”,这会引起意外和头痛。叹...解决方法是将警告C4239变成错误。这样可以防止MSVC编译试图将非常量左值引用绑定到临时代码的代码,并给您带来清晰的编译器错误。只需将其添加/we4239到编译器定义或cl命令行参数即可。在Visual Studio中:项目属性> C / C ++>所有选项>将特定警告视为错误> add 4239,并确保用分号分隔任何其他数字。在CMake中:if(MSVC)    add_definitions("/we4239")endif()这似乎比远好工作禁用所有语言扩展用/Za,从而正式不推荐。在我的大型代码库中,添加代码/Za导致Microsoft自己的winnt.h标头导致1500多个编译器错误。
随时随地看视频慕课网APP
我要回答