overloading template<class T> operator>> for vector<T>

Hi, i want to ask for advice how this one thing could be done.

I want to overload this operator
1
2
template<class T>
std::istream& operator>>(std::istream& is, vector<T>& vec)


The problem is - as far as i understand i have to at 1st create
1. T default_value; //using default constructor
2. than is >> default_value;
3. only than vec.pushback(default_value);
4. and repeat 2 and 3 again and again as long as i need.

But what if in some cases T has no default constructor? Than this code T default_value; would not work out.

How could i make this work if i need to store all these values in my vector?


Here is the code :
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
29
30
31
32
33
34
35
36
template<class T>
std::istream& operator>>(std::istream& is, std::vector<T>& vec){

	// { val , val , val , ... , val }

	char comma, brackets;
	
	is >> brackets;
	if (brackets != '{'){
		is.clear(std::ios_base::failbit);
		return is;
	}
	
	is >> brackets;
	if (brackets == '}'){
		// vector will be empty
		return is;
	}
	else is.putback(brackets);

	T temp = T();   // Here compiler gives me error if T has no default constructor

	while (is >> temp){
		vec.push_back(temp);
		is >> comma;
		if (comma == ',') {}
		else if (comma == '}') return is;  //end of vector
		else { 
			is.clear(std::ios_base::failbit);
			return is;  // something went wrong
		}
	}
	is.clear(std::ios_base::failbit);
	return is;

}

Last edited on
Any ideas?
I think the error is more likely that you don't have a copy constructor. At any rate, why can't you just use T temp;?
No its still the same problem
Error	1	error C2512: 'S<int>' : no appropriate default constructor available

So the problem is i cant use this cin >> vec for vectors that contain elements without default constructors. But i bet there is a way to fix this. Maybe some clever trick or writing this all function differently?
Are you sure that it's giving you an error for that line? I compiled the code in your post with no problem. I also ran a (simple) test with no problem:

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
#include <iostream>
#include <vector>

template <class T>
struct myClass
{
    T val;
};

template <class T>
std::istream& operator>>(std::istream& is, myClass<T>& mc)
{
    is >> mc.val;
    return is;
}

//insert your code here

int main()
{
    std::vector<myClass<int> > v;
    std::cin >> v;
    for (int i = 0; i < v.size(); ++i)
        std::cout << v[i].val << ' ';
    return 0;
}
{ 1, 2, 3, 4, 5, 6, 7, 8, 9 } //input
1 2 3 4 5 6 7 8 9 //output
So the problem is i cant use this cin >> vec for vectors that contain elements without default constructors. But i bet there is a way to fix this. Maybe some clever trick or writing this all function differently?


None that I can think of.

The only other alternative I can think of would be to clone/copy construct an existing element in the vector instead of default constructing one -- but that has the same problem if the class doesn't have a copy constructor.

You could side-step this with a 'read' style function instead of a >> overload:

1
2
3
4
5
6
7
8
template<typename T>
void read(std::istream& is, std::vector<T>& vec, T obj = T())
{
    //... 
    is >> obj;
    vec.push_back(obj);
    //...
}


Now if the object does not have a default ctor, you can call the function with any ctor:

 
read( is, vec, MyObject(15,"whatever") );


The downside is that now a copy ctor is mandatory.

And I guess not having >> semantics is also a downside (though not IMO. I freaking hate that iostream overloaded that operator).
@fg109
Are you sure that it's giving you an error for that line? I compiled the code in your post with no problem. I also ran a (simple) test with no problem:


Isn't compiler generates some kind of default constructor in this case?
1
2
3
4
5
template <class T>
struct myClass
{
    T val;
};


In my code there was only this kind of constructor and actually i had copy constructor but as u said I could also have just used T temp instead of T temp = T(). I think if u would try to run this it wouldn't run.
1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
struct S{
	
	S(T value) : val( value ){}

	T& get();
	const T& get() const;
	void set(T);
	S<T>& operator=(const T&);

private:
	T val;
};


@Disch
This is actually very good idea!!
void read(std::istream& is, std::vector<T>& vec, T obj = T())
I could even return bool to use this function in while(read(cin, ..., ...))


Thanks you guys both a lot, really appreciate!!! :)
Last edited on
Topic archived. No new replies allowed.