I want to add operator<<
to std::vector<string>
.
This is the operator
std::vector<std::string>& operator<<(std::vector<std::string>& op, std::string str) {
op.push_back(str);
return op;
}
Now I can add elements to vector this way:
std::vector<std::string> vec;
vec << "aaa" << "bbb" << "ccc";
But the following code isn’t compiled since cant pass temporary object by reference.
std::vector<std::string>() << "AAA" << "BBB";
How can I change the code to add elements to temporary vectors too?
I have a function which accepts const std::vector<std::string>&
argument so I want to pass to it a vector in one line.
You can't. The only way it could be achieved would be if your operator was a member of the vector. (For some reason member functions can be invoked on temporaries).
As a nonmember function though what you're after is impossible
Also it's not a very good idea to overload operators for STL types such as std::vector. I think what you're trying to accomplish is already present in boost assign library. I don't believe you can write it better than they have, so better use boost if you need this.
I haven't actually thought about the consequences of this properly, but it seems you could have an overload for rvalues:
std::vector<std::string> operator<<(std::vector<std::string>&& op, std::string str) {
op.push_back(std::move(str));
return op;
}
Yes, it returns by value, but it will be optimized to a move due to §12.8/32:
When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
Well... technically it is doable but in dirty style. Just for illustration (I'm not so sure it worth real implementation). Checked to work with GCC 4.7.2. I really don't know how this will behave on constant objects.
#include <vector>
#include <string>
#include <iostream>
const std::vector<std::string>& operator << (const std::vector<std::string>& op, const std::string &str)
{
((std::vector<std::string>&) op).push_back(str);
return op;
}
int main()
{
std::vector<std::string> a = std::vector<std::string>() << "A" << "B";
a << "AAA";
std::cout << "size: " << a.size() << std::endl;
for (std::vector<std::string>::iterator i = a.begin(); i != a.end(); ++i)
{
std::cout << '\t' << *i << std::endl;
}
return 0;
}
This is a code, that helps you to do something similar to your idea (http://ideone.com/3lrTxW):
#include <vector>
#include <string>
typedef std::string String;
typedef std::vector<String> StringVector;
class StringVectorWrapper {
StringVector vector;
public:
operator StringVector&() {
return vector;
}
StringVectorWrapper& operator << (const String& str) {
vector.push_back(str);
return *this;
}
};
And an example of use:
#include <iostream>
void printVector(const StringVector& vector) {
for(StringVector::const_iterator it = vector.begin(); it != vector.end(); it++)
std::cout << *it << std::endl;
}
int main(void) {
StringVectorWrapper w;
w << "A" << "B";
printVector(w);
printVector(StringVectorWrapper() << "Z" << "W");
return 0;
}
But I would not use such a code in any of my programs.
I'm afraid this is not possible. Also it's a bad idea to overload operator for any standard library class. The STL is not meant to be extended.