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?
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 == ',') {}
elseif (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;
}
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:
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).
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.
@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!!! :)