这是一个非常小的示例:

class Foo
{
public:
    Foo(int x) {};
};

void ProcessFoo(Foo& foo)
{
}

int main()
{
    ProcessFoo(Foo(42));
    return 0;
}

上面的代码在Visual Studio上可以正常编译,但是在Linux和Mac上会产生错误。

编译上面的代码会生成:
$ g++ -std=c++11 -c newfile.cpp

newfile.cpp: In function ‘int main()’:
newfile.cpp:23:23: error: invalid initialization of non-const reference of type ‘Foo&’ from an rvalue of type ‘Foo’
     ProcessFoo(Foo(42));
                       ^
newfile.cpp:14:6: note: in passing argument 1 of ‘void ProcessFoo(Foo&)’
 void ProcessFoo(Foo& foo)

我发现了三种解决方法:
  • 避免在调用ProcessFoo时使用内联temp变量。

  • 像这样:
    Foo foo42(42);
    ProcessFoo(foo42);
    
  • ProcessFoo采用const引用:void ProcessFoo(const Foo& foo)
  • ProcessFoo只是让Foo按值传递。 void ProcessFoo(Foo foo)

  • 为什么编译器禁止我的原始代码? (它在防什么)?满足编译器要求的上述三个变通办法分别是什么? MSVC允许什么,但g++不允许?

    最佳答案

    根据设计,C++仅允许将临时变量传递给const引用,值或rvalue引用。想法是,采用非常量引用参数的函数表示它想修改参数并允许其返回给调用者。临时执行此操作是没有意义的,并且很可能是错误。

    而且我不知道您正在运行的是哪个版本的g++。在这里不起作用:http://coliru.stacked-crooked.com/a/43096cb398cbc973

    10-08 14:21