3

我想添加operator<<std::vector<string>. 这是运营商

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

现在我可以通过这种方式将元素添加到向量:

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

但是由于无法通过引用传递临时对象,因此未编译以下代码。

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

如何更改代码以将元素也添加到临时向量?

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

4

5 回答 5

2

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

作为一个非成员函数,虽然你所追求的是不可能的

此外,为 std::vector 等 STL 类型重载运算符也不是一个好主意。我认为您要完成的工作已经存在于boost 分配库中。我不相信你能比他们写得更好,所以如果你需要的话,最好使用 boost。

于 2013-03-23T20:22:43.110 回答
2

我实际上并没有正确考虑过这样做的后果,但似乎你可能对右值有一个重载:

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

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

当满足或将满足复制操作的省略标准时,除了源对象是函数参数的事实,并且要复制的对象由左值指定时,选择复制的构造函数的重载决策是首先执行好像对象是由右值指定的。

于 2013-03-23T20:33:17.017 回答
1

嗯......从技术上讲,它是可行的,但风格很肮脏。只是为了说明(我不太确定它是否值得真正实施)。检查可与 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;
}
于 2013-03-23T20:43:07.137 回答
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;
}

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

于 2013-03-23T21:28:05.730 回答
-1

恐怕这是不可能的。此外,为任何标准库类重载运算符也是一个坏主意。STL 并不意味着扩展。

于 2013-03-23T20:22:34.793 回答