我想在队列中存储一串字符串。如果我使用成员函数push()
queue test;
string s0("s0"), s1("s1");
test.push(s0);
test.push(s1);
我正在考虑以隐式方式在队列中添加字符串。这意味着,如果我键入以下字符串序列,例如operator >>
应该在队列中推送字符串值。
queue test;
string s0("s0"), s1("s1");
s0 >> s1 >> s2 >> s3 ;
有没有办法做到这一点?
答案 0 :(得分:16)
虽然C ++不允许这样做,但它允许你做一些非常相似的事情:test << s0 << s1;
然而, 不这样做!
如果我看到test.push(s0)
,我确切地知道它的作用,甚至没有看test
的类型。如果我看到test << s0 << s1;
,我认为test
是一个写入的流。
这是我的在重载运算符时应该遵循的三个基本规则:
+
运算符的代码来更改其右操作数。但是,此类运算符的用户永远不会怀疑表达式a + b
来更改b
的值。这就是为什么运算符重载的第二条规则说: 始终坚持运算符的众所周知的语义。 (反过来,这假定语义是无可争议的;请参阅以前的规则。)a + b
,则用户也可以拨打a += b
。如果它支持前缀增量++ a,那么他们也希望++能够工作。如果他们可以检查是否a < b
,他们肯定也希望能够检查是否a > b
。如果他们可以复制构造您的类型,他们希望分配也可以工作。因此,运营商重载的第三条规则会提醒您: 始终提供一系列相关操作。 与所有这些规则一样,确实有例外。有时人们偏离了它们,结果并不是错误的代码,但这种偏差很少而且很远。至少,我所看到的100个这样的偏差中有99个是没有道理的。然而,它可能只有1000中的999。所以你最好坚持这些规则。
所以,以防我不够清楚:对于你问题的代码,偏离这些规则是非常糟糕的。
答案 1 :(得分:3)
首先,你的'隐式'排队项目的例子没有提到队列 - 你的意思是:
test << s0 << s1 << s2 << s3;
如果是这样,它可能是 ,但我不推荐它。它真的无法提供可读性。但是,如果你真的想要它,可以将它放在某个地方的标题中,并将它包含在你想要这种行为的任何地方:
template<typename T>
std::queue<T> &operator<<(std::queue<T> &q, const T &v)
{
q.push(v);
return q;
}
请注意,由于C ++优先级规则,相反的顺序 - s0 >> s1 >> s2 >> test
- 不可能。
答案 2 :(得分:3)
我不会真的这样做,但如果你真的觉得需要提供这种语法,你可以编写一个插件适配器......
template <typename C>
class inserter_type {
public:
typedef C container_type;
typedef typename container_type::value_type value_type;
explicit inserter_type( container_type & container ) : container(container) {}
inserter_type& operator<<( value_type const & value ) {
container.push( value );
return *this;
}
private:
container_type & container;
};
template <typename C>
inserter_type<C> inserter( C & container ) {
return inserter_type<C>(container);
}
int main() {
std::queue<std::string> q;
inserter(q) << "Hi" << "there";
}
答案 3 :(得分:2)
Qt容器的工作原理如下:
QStringList list;
list << "Sven" << "Kim" << "Ola";
QVector<QString> vect = list.toVector();
// vect: ["Sven", "Kim", "Ola"]
如果您希望使用相同的STL容器,则需要自己编写运算符重载,但显然您无法向std命名空间添加操作。
答案 4 :(得分:0)
如果您想这样做,通常会表示为
test << s0 << s1 << s2 << s3;
通过在队列类上重载operator<<
的合适定义。我不知道为什么这会比一系列简单的test.push()
电话更好。
答案 5 :(得分:0)
我同意大多数答案,这些答案告诉你,只要你包括队列对象,你就可以做到,而且我也同意可读性受到损害,因为它是非常非标准行为
不过,我很想知道。如果您尝试以下内容怎么办?
queue test;
string s0("s0"), s1("s1");
test.push(s0).push(s1);
这可以非常简单地实现,仍然会给你正确的可读性(因为push
的含义很好理解),并保持你的代码简洁(这似乎是你的主要目标)。
要实现它,您所要做的就是扩展Queue类(或者编写自己的队列类,然后再绕过STL Queue对象)。