如何使函数参数容器独立

cpp*_*der 6 c++ templates iterator

我正在编写一个实用程序函数,它将获取元素的向量(可以是string,int,double,char)并连接成一个字符串并返回它.它看起来像这样:

template<typename T>
std::string convert2Str(std::vector<T> const& vec) 
{
   std::ostringstream sStream; 
   for (size_t k=0; k<vec.size(); ++k) {
      sStream << vec[k] << " "; 
   }
   return sStream.str(); 
}
Run Code Online (Sandbox Code Playgroud)

我想使这个功能更通用:

  • 首先使用迭代器而不是使用索引vector<T>.我std::vector<T>::const_iterator it = vec.begin()在循环之前尝试了这个 并且编译器给了我一个错误:: error:;在它之前预期当我改变上面的定义时std::vector<std::string>::const_iterator it = vec.begin(),错误就消失了.所以,看起来我没有遵循正确的语法,请让我知道它是什么
  • 其次是通过使第一个参数容器独立来使函数更通用.鉴于任何容器(vector,list,queue,deque,等),我想要做上述同样的事情.我尝试在stackoverflow中搜索这个并没有找到满意的答案.

Ben*_*igt 5

如你所说,第1步使用迭代器:

template<typename T>
std::string convert2Str(std::vector<T> const& vec) 
{
   typedef std::vector<T> container;
   std::ostringstream sStream; 
   for (typename container::const_iterator it = vec.begin(); it != vec.end(); ++it) {
      sStream << *it << " "; 
   }
   return sStream.str(); 
}
Run Code Online (Sandbox Code Playgroud)

第2步,使模板参数成为容器类型而不是元素类型(您可以使用以下命令获取元素类型value_type:

template<typename container>
std::string convert2Str(container const& vec)
{
   typedef container::value_type T; // if needed
   std::ostringstream sStream; 
   for (typename container::const_iterator it = vec.begin(); it != vec.end(); ++it) {
      sStream << *it << " "; 
   }
   return sStream.str(); 
}
Run Code Online (Sandbox Code Playgroud)

在C++ 0x中,这变得更简单(并且typename不需要):

template<typename container>
std::string convert2Str(container const& vec)
{
   using std::begin;
   using std::end;
   std::ostringstream sStream;
   for (auto it = begin(vec); it != end(vec); ++it) {
      typedef decltype(*it) T; // if needed
      sStream << *it << " "; 
   }
   return sStream.str(); 
}
Run Code Online (Sandbox Code Playgroud)

其他优点std::beginstd::end原始阵列的工作.


Ale*_*nov 5

按照STL练习,我建议使用两个迭代器作为输入参数,而不是容器(显然原因是只能处理容器的一部分,通常使用迭代器定义的任何序列):

template<typename InputIterator>
std::string convert2Str(InputIterator first, InputIterator last)
{
    std::ostringstream sStream;
    for (InputIterator it = first; it != last; ++it) {
       sStream << *it << " ";
    }
    return sStream.str();
}
Run Code Online (Sandbox Code Playgroud)

如果您需要包含对象的类型,请使用

typedef typename std::iterator_traits<InputIterator>::value_type T;
Run Code Online (Sandbox Code Playgroud)

补充:您可以使用以下功能:

std::vector<int> int_vec;
std::list<float> f_list;
std::deque<std::string> str_deq;

     // put something into the containers here

std::cout<< convert2Str(int_vec.begin(), int_vec.end()) <<std::endl;
std::cout<< convert2Str(f_list.begin(), f_list.end()) <<std::endl;
std::cout<< convert2Str(str_deq.begin(), str_deq.end()) <<std::endl;
Run Code Online (Sandbox Code Playgroud)

请注意,您无法遍历std :: queue; 但如果您确实需要它,该标准可确保为自己动手解决方案提供足够的支持.在这里查看更多信息:std :: queue iteration.