将运算符<<添加到 std::vector

Add operator<< to std::vector

本文关键字:lt 运算符 vector std 添加      更新时间:2023-10-16

我想将operator<<添加到std::vector<string>。这是运算符

std::vector<std::string>& operator<<(std::vector<std::string>& op, std::string str) {
    op.push_back(str);
    return op;
}

现在我可以这样给vector添加元素:

std::vector<std::string> vec;
vec << "aaa" << "bbb" << "ccc";

但是下面的代码不能被编译,因为不能通过引用传递临时对象。

std::vector<std::string>() << "AAA" << "BBB";

我怎么能改变代码添加元素到临时向量太?

我有一个接受const std::vector<std::string>&参数的函数,所以我想在一行中传递一个向量给它。

你不能。实现的唯一方法是操作符是vector的成员。(由于某些原因,成员函数可以在临时对象上调用)。

作为非成员函数是不可能的

对于std::vector等STL类型重载操作符也不是一个好主意。我认为你想要完成的任务已经存在于boost assign库中。我不相信你能写得比他们更好,所以如果你需要的话最好使用boost。

我还没有真正考虑过这样做的后果,但似乎你可以重载右值:

std::vector<std::string> operator<<(std::vector<std::string>&& op, std::string str) {
  op.push_back(std::move(str));
  return op;
}

是的,它按值返回,但是由于§12.8/32,它将被优化为移动:

如果满足或将满足省略复制操作的条件(除了源对象是函数形参,且要复制的对象由左值指定),则首先执行选择复制构造函数的重载解析,就像对象由右值指定一样。

嗯…从技术上讲,这是可行的,但在肮脏的风格。只是为了说明(我不确定它是否值得真正实现)。选中以与GCC 4.7.2一起使用。我真的不知道这在常量对象上会有什么表现。

#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;
}

这是一个代码,可以帮助你做一些类似于你的想法(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;
    }
};

和使用的例子:

#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;
}

但是我不会在我的任何程序中使用这样的代码。

恐怕这是不可能的。此外,为任何标准库类重载操作符也是一个坏主意。STL不能被扩展