vector.insert() and operator overloading

Hey all,

In my program, I have a class Route. It has a vector<string> property. After an initial vector has been populated, the user may have to concatenate another vector<string> to that initial vector. How can I overload the '+' operator to add to Route objects together and return the concatenated value?


Basically:

vector<string> vector1;
vector<string> vector2;
vector3;
vector3 = vector1.insert(vector1.begin(), vector2.begin(), vector2.end());


Should equal

vector1 + vector2 = vector3;

or

Route obj1;
Route obj2;
Route obj3;


obj1 + obj2 = obj3; <- object 3 should have the vector3 value

??


Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector>

template <typename T>
std::vector<T> operator+(const std::vector<T>& A, const std::vector<T>& B)
{
	std::vector<T> AB;
	AB.reserve( A.size() + B.size() ); // preallocate memory
	AB.insert( AB.end(), A.begin(), A.end() );
	AB.insert( AB.end(), B.begin(), B.end() );
	return AB;
}

void print(const std::vector<int>& vec)
{
	for (const int i : vec)
		std::cout << i << ' ';
	std::cout << '\n';
}

int main()
{
	std::vector<int> a = {3, 2, 1};
	std::vector<int> b = {4, 5, 6, 7};
	std::vector<int> c = a + b;
	print(c);
	return 0;
}


Of course, this only works because the standard library doesn't already define the operator+ between two vectors.

Personally, I would probably stick with a normal function, but I guess that's personal taste.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <vector>
using namespace std;

template <typename T> vector<T> operator + ( vector<T> A, const vector<T> &B )
{
   A.insert( A.end(), B.begin(), B.end() );
   return A;
}


template <typename T> ostream & operator << ( ostream &out, const vector<T> &V )
{
   for ( auto e : V ) out << e << ' ';
   return out;
}


int main()
{
   vector<string> A = { "Manchester", "Liverpool", "Leeds" }, B = { "London", "Oxford", "Norwich" };

   cout << "A: " << A << '\n';
   cout << "B: " << B << '\n';
   cout << "A+B: " << A + B << '\n';
}


A: Manchester Liverpool Leeds 
B: London Oxford Norwich 
A+B: Manchester Liverpool Leeds London Oxford Norwich 
1
2
3
4
5
6
7
8
9
10
11
12
13
class Route{
   std::vector<std::string> v;
public:
   Route& operator+=(const Route &b){
      this->v.insert(this->v.end(), b.v.begin(), b.v.end());
      return *this;
   }
};
Route operator+(Route a, const Route &b){
   return a += b;
}

obj3 = obj1 + obj2;



if you overload the operator+ for std::vector, then you should put it on the std namespace
I would not recommend such name pollution (also, I would expect it to mean per element +)
Last edited on
@ne55 you think it would be better just to use the insert function? I'm also just trying to get a grasp on operator overloading.
no, I think that's fine to overload operator+ for `Route' objects
however, I object to overload it for std::vector
1
2
3
Route operator+(Route a, const Route& b) {
		return a += b;
	}


I get an error for this saying there are too many parameters for this operator function.
Last edited on
¿did you put that inside your class?
I did not write it as a member function.

show enough code to reproduce your issue
I have two files for my class. My Route.cpp and my Route.h

Route.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Route.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

Route::Route() {}
Route::someFunc (someStringParameter string) {…}
Route::someotherFunc() {…}

//putting the function in your class here
Route& operator+=(const Route& b) {
	this->v.insert(this->v.end(), b.v.begin(), b.v.end());
	return *this;
}


main file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<fstream>
#include "Route.h"

int main (int argc, int** argv) {…}



//putting the function outside of your class here

Route operator+(Route a, const Route &b){
   return a += b;
}


I get a few errors.

Inside the class function there are too few parameters for the operator function. I think + needs 2. And the "this" may only be used with non-static member functions?

Also, below the main, I get "No operator '+=' matches these operands. Operand types are: Route += const Route.

Do I need to declare in my Route.h as well? That file is the same as my Route.cpp just as declarations.
Last edited on
If you're calling a function before you define it, then yes you need a separate declaration. You should put the definition of operator+ in route.cpp anyway to keep things consistent.

If that doesn't help, I'll repeat ne555's advice:
show enough code to reproduce your issue

Let us be able to at least attempt to compile your code. Make a minimal example that still reproduces the compiler error.
Last edited on
Your operator+=() function is malformed. The fact that you defined it as Route& operator+=(const Route& b) rather than Route& Route::operator+=(const Route& b) (note the class scope '::') looks like a non-member function. The fact that you only have 1 argument and try to dereference the this pointer makes it look like you are defining a member function.

Either add the Route:: to the function definition and make it a member function or add an argument to the function and leave it a non-member function.

Hey ya'll, I figured it out. Here is my member function in the .cpp file.


1
2
3
4
5
6
Route Route::operator+(const Route b) {

	this->raw_route.insert(this->raw_route.end(), b.raw_route_piece.begin(), b.raw_route_piece.end());
	return *this;

}


And my declaration in the Route.h file.


Route operator+(const Route);

this adds the vector<string> characteristics of the objects.
Last edited on
err, it is not expected for + to modify its argument
c = a+b your code will change `a', which is weird.
I see what you mean. I mean intended that but I understand what you mean by it being weird. I'll edit it to fix that problem.
I realized that I had the variables in there a little funky, I edited them in my program. It returns a third object with the two vectors concatenated. I'll double check it.
Here ya go, this one doesn't change the original route.

1
2
3
4
5
6
7
8
9
10
11
Route Route::operator+(const Route b) {
	
	Route new_route;
	new_route.raw_route = this->raw_route;
	
	new_route.raw_route.insert(new_route.raw_route.end(), b.raw_route_piece.begin(), b.raw_route_piece.end());

	
	return new_route;

}
Topic archived. No new replies allowed.