-2

Note upfront: The problem relates to a vector-class implemented by myself, and has nothing to do with std::vector

Consider the following operator-overloading:

//in the Vector-class(declaration)
friend Vector operator+(const Vector& a, const Vector& b);

//outside the Vector-class(implementation)
Vector operator+(const Vector& a, const Vector&b) {
//...
}

It takes references to two vectors, and returns their sum. Now when i try something like the following:

Vector foo();
Vector bar();

Vector byVal = foo + bar; //using objects
Vector byRef = &foo + &bar; //using address

in both cases my IDE tells me the following:

expression must have integral or unscoped enum-type

In the second case this makes sense, because i would only pass a yielded pointer when the called function would take a pointer, and for a function that takes a reference, i can pass the object itself, but i don't understand why just using the object is not possible here.

What makes it more confusing for me, is that the following seems to be possible:

Vector* foo = new Vector();
Vector* bar = new Vector();

Vector foobar = *foo + *bar;

That is i can use de-referenced pointers with the overloaded operator.

What is the cause of this behaviour, and how am i supposed to use my overloaded operator in this case?

  • 2
    `Vector byRef = &foo + &bar; //by reference` That will pass the addresses of `foo` and `bar` to call the operator function. You seem to have some serious misconception about how reference parameters work. – πάντα ῥεῖ Jun 27 '19 at 17:27
  • 1
    The answers already address your problem. Yet, I still would like to recommend the following video to you, for learning about passing values to functions: https://www.youtube.com/watch?v=PNRju6_yn3o – jan.sende Jun 27 '19 at 17:41
  • @πάνταῥεῖ i think my problem lied more in the definition of 'passing by reference' vs. 'passing by value' which this post https://stackoverflow.com/questions/410593/pass-by-reference-value-in-c helped to make a bit clearer for me. I edited my question, and hopefully my statements are more correct now. – LeonTheProfessional Jun 27 '19 at 17:44
  • @ancientchild I probably should have closed your question as a dupe of the one you linked to, yes. – πάντα ῥεῖ Jun 27 '19 at 17:46

2 Answers2

2
Vector foo();
Vector bar();

These are not variable declarations. These are function declarations. They are functions that return Vector and take an empty argument list.

Given that you cannot add functions together, nor can you add function pointers together, foo + bar and &foo + &bar are both ill-formed.

In order to value-initialise a variable, you can use either of the following:

Vector foo{};        // uniform initialsation
auto bar = Vector(); // copy initialisation syntax

I wanted to call the constructor of Vector, that doesn't take any arguments

Indeed. Declaration of a function with no arguments, and a variable declaration with empty initialiser list are ambiguous. This is resolved by a language rule that says if a piece of code could syntactically be either a function declaration or something else, then it is a function declaration.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Oh, i see, thanks! I wanted to call the constructor of Vector, that doesn't take any arguments, like in the way i am used to calling constructors that take arguments, but instead i declared two functions that return a Vector. – LeonTheProfessional Jun 27 '19 at 17:49
1

If a function marks a parameter as &, then an object passed as argument will be passed by reference. The address of the object is taken implicitly, so you don't have to (actually must not) write an & before the argument object to be passed.

Note further that Vector foo(); declares a function, not an object. That's why your compiler complains about both of your calls.

Vector operator+(const Vector& a, const Vector&b) {
//...
}

Vector foo;
Vector bar;

Vector byVal = foo + bar; //by reference because parameter in operator + is marked as "call by reference" 
// Wrong: Vector byRef = &foo + &bar; 
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • 1
    Note that OP seems to have attempted value initialisation. `Vector foo;` is not value initialisation, but default initialisation instead. This is different if `Vector` is trivially constructible. – eerorika Jun 27 '19 at 17:43