C++ 如何在具有迭代器的stl容器上模板化函数

C++ 如何在具有迭代器的stl容器上模板化函数,c++,templates,C++,Templates,我想写一个函数,将采取stl容器(如集,向量或列表) 然后对内容进行迭代,然后将其附加到字符串并返回该字符串 像这样的 // I dont know how to do this. Just using stl::container for meanings sake Not sure if such a thing exists? template<typename T, typename Container = stl::container<T> > void J

我想写一个函数,将采取stl容器(如集,向量或列表) 然后对内容进行迭代,然后将其附加到字符串并返回该字符串

像这样的

// I dont know how to do this. Just using stl::container for meanings sake Not sure if such a thing exists?
template<typename T, typename Container = stl::container<T> >  
void JoinToString(const Container<T> cont, const char * delim, string &str)
{
   stringstream s;
   Container<T>::const_iterator it = cont.begin, last = cont.end();
   while(it != last)
   {
       s<<(*it);
       ++it;
       if(it == last)
           break;
       s<<delim;
   }
   str = s.str();
} 
//我不知道怎么做。仅仅使用stl::container是为了不确定是否存在这样的东西?
样板
void JoinToString(常量容器cont、常量字符*delim、字符串和str)
{
细绳;
Container::const_迭代器it=cont.begin,last=cont.end();
while(它!=最后一个)
{
看一看

这样的函数不存在。

请查看


这样的函数不存在。

您需要决定需要什么。您可以传递类型或模板。不能同时传递两者。在您发布的代码中,您将容器声明为be类型,但将其用作模板

template<typename T, typename Container = vector<T> > 
void test() { Container x; };

template<typename T, template <typename> class Container = vector > 
void test() { Container<T> x; } 
模板
void test(){Container x;};
样板
void test(){Container x;}

您需要决定您想要什么。您可以传递类型或模板。不能同时传递两者。在您发布的代码中,您将容器声明为be类型,但将其用作模板

template<typename T, typename Container = vector<T> > 
void test() { Container x; };

template<typename T, template <typename> class Container = vector > 
void test() { Container<T> x; } 
模板
void test(){Container x;};
样板
void test(){Container x;}

您的解决方案几乎正确。只需执行以下操作:

template<typename Container >  
string JoinToString(const Container & cont, const string &delim)
{
    stringstream s;
    for (Container::const_iterator it = cont.begin(); it != cont.end(); it++ )
    {
            s<<(*it);
            if ( (it+1) != cont.end() )
                   s<<delim;
    }
    return s.str();
} 
模板
字符串连接字符串(常量容器和cont、常量字符串和delim)
{
细绳;
对于(Container::const_迭代器it=cont.begin();it!=cont.end();it++)
{

您的解决方案几乎是正确的。只需执行以下操作:

template<typename Container >  
string JoinToString(const Container & cont, const string &delim)
{
    stringstream s;
    for (Container::const_iterator it = cont.begin(); it != cont.end(); it++ )
    {
            s<<(*it);
            if ( (it+1) != cont.end() )
                   s<<delim;
    }
    return s.str();
} 
模板
字符串连接字符串(常量容器和cont、常量字符串和delim)
{
细绳;
对于(Container::const_迭代器it=cont.begin();it!=cont.end();it++)
{

St>样式是在代码< >开始>代码>和<代码>结束>代码>迭代器到任何算法,而不是容器本身:这使事物保持一般性,允许使用指针的本机向量。一般C++风格的考虑也建议返回<代码> STD::String < /C>而不是使用引用参数。

STL样式是在代码< >开始> <代码>和<代码>结束>代码>迭代器到任何算法,而不是容器本身:这使事物保持一般性,允许使用指针的本机向量。一般C++风格的考虑也建议返回<代码> STD::String < /C>而不是使用引用参数。访问容器,然后执行您想要的操作:

template<typename Container>  
void JoinToString(const Container& cont, const char * delim, string &str)
{
  typedef typename Container::value_type T;
  ...
}
模板
void JoinToString(常量容器和cont、常量字符*delim、字符串和str)
{
typedef typename容器::value_type T;
...
}
但是,更惯用的方法是使用如下迭代器范围:

template<typename FwdIt>  
void JoinToString(FwdIt it, FwdIt end, const char * delim, string &str)
{
  typedef typename std::iterator_traits<Container::iterator>::value_type T;
  while(it != end)
  {
     ...
  }
}
模板
void JoinToString(FwdIt,FwdIt end,const char*delim,string&str)
{
typedef typename std::iterator_traits::value_type T;
while(it!=结束)
{
...
}
}

如果您确实需要访问容器,那么这将满足您的需要:

template<typename Container>  
void JoinToString(const Container& cont, const char * delim, string &str)
{
  typedef typename Container::value_type T;
  ...
}
模板
void JoinToString(常量容器和cont、常量字符*delim、字符串和str)
{
typedef typename容器::value_type T;
...
}
但是,更惯用的方法是使用如下迭代器范围:

template<typename FwdIt>  
void JoinToString(FwdIt it, FwdIt end, const char * delim, string &str)
{
  typedef typename std::iterator_traits<Container::iterator>::value_type T;
  while(it != end)
  {
     ...
  }
}
模板
void JoinToString(FwdIt,FwdIt end,const char*delim,string&str)
{
typedef typename std::iterator_traits::value_type T;
while(it!=结束)
{
...
}
}

这是一个工作示例

template<typename T>  
std::string JoinToString(const T& cont, const char* delim, std::string &str)
{
   std::stringstream s;
   T::const_iterator it= cont.begin();
   T::const_iterator last= cont.end();
   while(it != last)
   {
      s << (*it);
      ++it;
      s << delim;
      if (it == last)
         break;
   }
   return s.str() + str;
} 

int main()
{
   std::string s("String! ");
   std::vector<std::string> v(1, "String!, String!");
   std::cout << JoinToString(v, ", ", s) << "\n";

   std::list<std::string> l(1, "String!, String!");
   std::cout << JoinToString(l, ", ", s);
}
模板
std::string JoinToString(常量T&cont,常量char*delim,std::string&str)
{
std::strings;
T::const_迭代器it=cont.begin();
T::const_迭代器last=cont.end();
while(它!=最后一个)
{

这是一个有效的例子

template<typename T>  
std::string JoinToString(const T& cont, const char* delim, std::string &str)
{
   std::stringstream s;
   T::const_iterator it= cont.begin();
   T::const_iterator last= cont.end();
   while(it != last)
   {
      s << (*it);
      ++it;
      s << delim;
      if (it == last)
         break;
   }
   return s.str() + str;
} 

int main()
{
   std::string s("String! ");
   std::vector<std::string> v(1, "String!, String!");
   std::cout << JoinToString(v, ", ", s) << "\n";

   std::list<std::string> l(1, "String!, String!");
   std::cout << JoinToString(l, ", ", s);
}
模板
std::string JoinToString(常量T&cont,常量char*delim,std::string&str)
{
std::strings;
T::const_迭代器it=cont.begin();
T::const_迭代器last=cont.end();
while(它!=最后一个)
{

s另一种完全满足您需求的解决方案是:

此算法将“列表”中的所有字符串合并为一个长字符串。段由给定的分隔符连接

使用示例:

#include <boost/algorithm/string/join.hpp>
#include <boost/assign/list_of.hpp>
#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> v = boost::assign::list_of("A")("B")("C");
    std::cout << boost::algorithm::join(v, "/") << std::endl;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
std::vector v=boost::assign::list_of(“A”)(“B”)(“C”);

std::cout另一个完全满足您需求的解决方案是:

此算法将“列表”中的所有字符串合并为一个长字符串。段由给定的分隔符连接

使用示例:

#include <boost/algorithm/string/join.hpp>
#include <boost/assign/list_of.hpp>
#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> v = boost::assign::list_of("A")("B")("C");
    std::cout << boost::algorithm::join(v, "/") << std::endl;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
std::vector v=boost::assign::list_of(“A”)(“B”)(“C”);

std::cout创建自定义输出迭代器:

struct append_to_string_with_delim
  : std::iterator<std::output_iterator_tag, void, void, void, void>
{
  append_to_string_with_delim(std::string &ss, char const *dd) : s(ss), d(dd)
  {
  }
  template<typename T>
  append_to_string_with_delim &operator=(T const &t)
  {
    std::ostringstream o;
    o << t;
    s += o.str();
    s += d;
    return(*this);
  }
  append_to_string_with_delim &operator*()
  {
    return(*this);
  }
  append_to_string_with_delim &operator++()
  {
    return(*this);
  }
  append_to_string_with_delim const &operator++(int)
  {
    return(*this);
  }
  std::string &s;
  char const *const d;
};
struct将\u附加到带有\u delim的\u字符串\u
:std::迭代器
{
将_附加到带有_delim的_字符串上(std::string&ss,char const*dd):s(ss),d(dd)
{
}
样板
将\u附加到\u字符串\u,并使用\u delim&operator=(T const&T)
{
std::ostringstream o;

o创建自定义输出迭代器:

struct append_to_string_with_delim
  : std::iterator<std::output_iterator_tag, void, void, void, void>
{
  append_to_string_with_delim(std::string &ss, char const *dd) : s(ss), d(dd)
  {
  }
  template<typename T>
  append_to_string_with_delim &operator=(T const &t)
  {
    std::ostringstream o;
    o << t;
    s += o.str();
    s += d;
    return(*this);
  }
  append_to_string_with_delim &operator*()
  {
    return(*this);
  }
  append_to_string_with_delim &operator++()
  {
    return(*this);
  }
  append_to_string_with_delim const &operator++(int)
  {
    return(*this);
  }
  std::string &s;
  char const *const d;
};
struct将\u附加到带有\u delim的\u字符串\u
:std::迭代器
{
将_附加到带有_delim的_字符串上(std::string&ss,char const*dd):s(ss),d(dd)
{
}
样板
将\u附加到\u字符串\u,并使用\u delim&operator=(T const&T)
{
std::ostringstream o;

o传递模板不是一件小事。对于初学者来说,您的代码在所有标准编译器中都会失败,因为
std::vector
容器至少包含两个类型参数。问题是,标准允许实现添加额外的参数,只要这些参数是默认的,也就是说,在完全一致的实现中
std::vector
可能有3、4、5…个参数。模板参数很难使用和维护,而且由于各种原因,包括David指出的原因,它们没有太多添加。我从来没有感觉到在生产代码中需要达到一个参数。传递模板并不简单。对于初学者来说,您的代码在所有标准c中都会失败ompilers,一个