例如,如果我想将"Hello"
和"World"
元素添加到名为std::vector<std::string>
的{{1}},我必须使用v
和{{ 1}}。
而不是这个,我想重载v.push_back("Hello")
运算符,所以我可以这样做:
v.push_back("World")
在我的头文件中,我有以下功能,但它不起作用:
<<
答案 0 :(得分:2)
v << "foo";
此左手操作数为vector<string>
,右手操作数为string
。所以这应该有效:
vector<string>& operator<<(vector<string>& v, const string& s) {
v.push_back(s);
return v;
}
但在我看来,这将不太可读,也不是一个好主意。
答案 1 :(得分:0)
vector<string>& operator<<(vector<string> &a,const string &b)
{
a.push_back(b);
return a;
}
答案 2 :(得分:0)
前进中的一个词:向量不是流,我宁愿不建议这样做。但是如果你坚持:你必须让你的矢量扮演通常流所做的角色,我。 E:
std::vector<std::string>& operator<<(std::vector<std::string>& v, std::string s);
嗯,当然,在实现中,你会调用push_back,当然......在推动从移动语义中获利时使用std::move
...
甚至可以将其作为模板:
template <typename T, typename V>
std::vector<T>& operator<<(std::vector<T>& c, V v)
{
c.push_back(T(std::move(v)));
return c;
}
这将允许将任何数据类型添加到任意类型的向量,只要向量的类型可以从给定的值构造...更好,因为C ++ 11:
c.emplace_back(std::move(v));
答案 3 :(得分:0)
我对此评论同意@Caleth:
这很有可能,但这是一个坏主意,特别是如果人 除了你将阅读你这样写的代码。
v.push_back("Hello")
是标准的,所以很容易理解你是什么 是做。v << "Hello";
会给人们带来惊喜,而惊喜也是不利的 理解。
所以只是简单地添加一个过载就像其他好的答案提出的不是我要做的事情。但是,我没有看到任何想要将内容“流”到向量中的内在坏处。把事情说清楚会更好,所以很明显我们正在使用自制的实用工具。所以让我们添加一个间接层:
template<typename T, typename A>
class vec_streamer {
std::vector<T, A>& target;
friend vec_streamer const& operator<<(vec_streamer const& self, T const& t) {
self.target.push_back(t); return self;
}
friend vec_streamer const& operator<<(vec_streamer const& self, T && t) {
self.target.push_back(std::move(t)); return self;
}
public:
vec_streamer(std::vector<T, A>& target) : target(target) {}
};
以上是一个方便的实用程序,允许我们编写此c++17代码( See it Live! ):
std::vector<int> v;
vec_streamer(v) << 1 << 2 << 3 << 4;
注意vec_streamer(v)
如何发送一个明确的消息,我们正在使用向量进行处理(并且它依赖于模板参数推导,因此需要C ++ 17)。关于这个的好处是,ADL可以找到operator<<
(事实上只有ADL),所以如果任何模板化代码使用operator<<
,我们可以传入vec_streamer(v)
并获得预期的行为。接受向量作为左参数的天真重载将不会从中受益。