The Welder
The Welder

Reputation: 1062

Opinions on this operator overload

this is more of an ask for opinions, rather than a specific difficulty that I'm having with my codebase. Take the following simple example:-

class Ref
{
    public:
        Ref(char* s, size_t l) : _s(s), _l(l) {}
    private:
        char* _s;
        size_t _l;
};

std::stringstream ss;

char a[256];
ss >> Ref(a, sizeof(a));   // <-------- here is the discussion line

friend std::stringstream& operator>>(std::stringstream& ss, Ref& r)
{
    // perform some functionality
}

Now when using Visual Studio the above compiles fine... It seems to figure out that when I use the operator >>, that because I have an override that takes a reference that I mean to pass the created object as a reference. However, when using gcc, it throws a wobbly. It complains that I have no operator overload for the operation.

Technically, I think gcc is correct because I am creating the object and essentially passing the object to the operator and not a reference to the object. I'm just wondering why the Microsoft compiler would allow this, or why gcc can't figure out that I'm intending to pass it by reference? In the above case, where the Ref object is fairly trivial, passing by reference or the object itself matters little, but if Ref was something more complex and heavy, then it probably could end up being an issue.

So, I'm asking people what they think about the above... and give some recommendations. Obviously you could construct Ref and pass by reference, or change the operator overload to take the object rather than a reference, but it's really a more about this difference between Visual Studio and gcc and what your opinion is.

Upvotes: 0

Views: 117

Answers (3)

juanchopanza
juanchopanza

Reputation: 227400

The problem is that you are attempting to bind a temporary to a non-const lvalue reference, which is not allowed in standard C++. Visual studio has an extension that makes your code compile, whereas GCC sticks to the standard.

You can bypass the problem entirely by not passing a temporary:

Ref r(a, sizeof(a)); 
ss >> r;

Upvotes: 1

jrok
jrok

Reputation: 55395

MSVC has got an extension that allows binding a reference to non-const to a temporary object. This is non-standard behaviour. Gcc doesn't have such an extension and rightfuly complains.

ss >> Ref(a, sizeof(a));
//    ^^^^^^^^^^^^^^^^^^
//    temporary

friend std::stringstream& operator>>(std::stringstream& ss, Ref& r)
//                                  reference to non-const  ^^^^^^  

Obviously you could construct Ref and pass by reference, or change the operator overload to take the object rather than a reference.

The latter isn't really an option if you need to use Ref object after the call to operator>>. The former is the way to go.

Upvotes: 2

Jesse Good
Jesse Good

Reputation: 52365

gcc is correct, you need const Ref& r for it to compile. Ref(a, sizeof(a)) creates a temporary and this can only be bound to constant lvalue references. The reason Microsoft compiles the code, is due to its non-conforming evil extension which allows non-const lvalue references to bind to temporaries. Compile with /W4 to get a warning about it.

Upvotes: 2

Related Questions