如何为std :: transform创建正确的接口

时间:2013-06-11 11:29:45

标签: c++ stl

变换的签名是:

OutputIterator transform (InputIterator first1, InputIterator last1,
                        OutputIterator result, UnaryOperation op);

我想创建一个通用标记替换下面的functor,msg_parser,所以我可以使用任何容器(下面的例子中使用的字符串)并传递容器的开始和结束进行转换。这个想法。

但我无法将其编译。

这是我的代码。任何帮助将不胜感激。

#include <iostream>
#include <iterator>
#include <string>
#include <map>
#include <algorithm>


class msg_parser {
public:
   msg_parser(const std::map<std::string, std::string>& mapping, const char token = '$')
      : map_(mapping), token_(token) {}

   // I can use a generic istream type interface to handle the parsing.   
   std::ostream_iterator operator() (std::istream_iterator in) {
      //body will go through input and when get to end of input return output

   }

private:
   const char token_;
   const std::map<std::string, std::string>& map_;
};


int main(int argc, char* argv[]) {
   std::map<std::string, std::string> mapping;
   mapping["author"] = "Winston Churchill";
   std::string str_test("I am $(author)");
   std::string str_out;
   std::transform(str_test.begin(), str_test.end(), str_out.begin(), msg_parser(mapping));
   return 0;
}

2 个答案:

答案 0 :(得分:3)

由于std::stringchar s的集合,std::transform将完全重复字符 distance(first1, last1)次,所以在您的情况下它&# 39;不可能改变字符串的大小。您可以将"$(author)"转换为另一个字符串完全相同的,但我想这不是您想要的。

您可能希望迭代流迭代器而不是chars:

std::stringstream istrstr(str_test);
std::stringstream ostrstr;
std::transform(std::istream_iterator<std::string>(istrstr), 
               std::istream_iterator<std::string>(), 
               std::ostream_iterator<std::string>(ostrstr, " "), // note the delimiter 
               msg_parser(mapping));

std::cout << ostrstr.str() << std::endl;

顺便说一句,你的UnaryOperation适用于迭代类型,而不适用于迭代器,所以operator()应该是:

std::string operator() (std::string in) { // ...

答案 1 :(得分:1)

您应该在this等参考中阅读std::transform的文档和示例。

您会注意到操作应采用输入容器的元素并为输出容器生成元素。由于您的容器是字符串且元素是字符,因此签名应为char operator()(char)。在这种情况下,容器迭代器是错误的。无论如何,std::string的迭代器都是char* s,所以你的std::ostream_iterator完全没有意义。

话虽如此,你会发现变换适用于单个字符,如果你将它应用于你的字符串,而不是整个“author”子字符串。您尝试做的最好是使用C ++ 11的std::regex正则表达式库,而不是std::transform