1

The following code raises an error on Linux when I compile with g++ test.cpp:

#include <iostream>

using namespace std;

class A
{
public:
    A(){
        cout << "call A()" << endl;
    };
    A& operator = (const A& a) {
        cout << "call operator =" << endl;
        return *this;
    }
    A(A& a) {
        cout << "call A(A& a)" << endl;
    }
};

A operator - (A& a1, A& a2)
{
    cout << "call operate -" << endl;
    return a1;
}

int main()
{
    A a1;
    A a2;
    A a3 = a1 - a2;
    //a1 = a2;
    return 0;
}

The error is:

test.cpp: In function ‘int main()’:
test.cpp:30: error: no matching function for call to ‘A::A(A)’
test.cpp:15: note: candidates are: A::A(A&)
test.cpp:8: note:                 A::A()

But it works on Windows when compiling with Visual Studio 2010. Why? What's wrong with my code on Linux?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
tidy
  • 4,747
  • 9
  • 49
  • 89
  • 1
    Note that your subtraction operator should also take constant references unless your actual implementation could modify one of the input parameters (but the implementation probably shouldn't be doing that in the first place). – Jonathan Leffler Nov 17 '14 at 06:32

1 Answers1

9

On line

A a3 = a1 - a2;

Here, you have substracted a1 and a2, resulting in a temporary value (a prvalue, technically). However, your copy constructor expects a non-const lvalue reference:

A(A& a) { ... }

This is not allowed by the C++ standard: prvalues cannot bind to non-const lvalue references. You should use a const reference parameter in your copy constructor instead:

A(const A& a) { ... }

As to why this is accepted by Visual C++, this appears to be a language extension retained for backward compatibility, according to Brian. See similar questions.

Community
  • 1
  • 1
Rufflewind
  • 8,545
  • 2
  • 35
  • 55
  • 2
    Visual Studio allows non-const lvalue references to bind to rvalues. It's a long-standing point of departure from the Standard that Microsoft won't fix because it would break too much code. – Brian Bi Nov 17 '14 at 06:26