Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使函数参数容器独立_C++_Templates_Iterator - Fatal编程技术网

C++ 如何使函数参数容器独立

C++ 如何使函数参数容器独立,c++,templates,iterator,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) { sStre

我正在编写一个实用函数,它将获取一个元素向量(可以是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(); 
}
模板
std::string convert2Str(std::vector const&vec)
{
std::ostringstream sStream;

对于(size_t k=0;k步骤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(); 
}
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();
}
在C++0x中,这变得更加简单(并且不需要
typename
):

模板
std::string convert2Str(容器常量和向量)
{
使用std::begin;
使用std::end;
std::ostringstream sStream;
对于(自动it=开始(vec);it!=结束(vec);+it){
typedef decltype(*it)T;//如果需要

sStream我认为这应该有效:

template<typename T>
std::string convert2Str(T const& container) 
{
   std::ostringstream sStream; 
   for (typename T::const_iterator i= container.begin(); i != container.end(); ++i) {
      sStream << *i << " "; 
   }
   return sStream.str(); 
}
模板
std::string convert2Str(T const和container)
{
std::ostringstream sStream;
对于(typename T::const_迭代器i=container.begin();i!=container.end();++i){

SsFrase

使用这个。您需要<代码> Type NeX/Cuth>部分,以便告诉编译器应该考虑<代码> t::CONTYSTATIORATOR 一个类型,而解析时,它不能真正知道这是真的,直到您真正调用的函数通过了一些<代码> t>代码>,它有一个<代码> CONTRORATIORATER < /COD>成员类型。

template<typename T>
std::string convert2Str(T const& cont) 
{
    std::ostringstream sStream; 
    for (typename T::const_iterator it = cont.begin(); it != cont.end(); ++it) {
        sStream << *it << " "; 
    }
    return sStream.str(); 
}
模板
std::string convert2Str(T const&cont)
{
std::ostringstream sStream;
对于(typename T::const_迭代器it=cont.begin();it!=cont.end();++it){

sStream如果您仅对容器类型进行模板化,那么最简单的方法就是将值类型存储在所有标准、Boost和Qt容器中,因为
typedef
成员
value\u type
std::copy
ostream\u迭代器
允许您跳过冗长的迭代器声明

template <typename Container>
std::string convert2Str(Container const &cont)
{
    std::ostringstream s;
    std::copy(cont.begin(), cont.end(),
              std::ostream_iterator<typename Container::value_type>(s, " "));
    return s.str();
}
模板
std::string convert2Str(容器常量和cont)
{
std::ostringstream s;
复制(继续开始(),继续结束(),
std::ostream_迭代器(“”);
返回s.str();
}

typename
是避免歧义所必需的。GCC的最新版本会在您忽略此关键字时发出警告。

根据STL实践,我建议使用两个迭代器作为输入参数,而不是容器(由于能够仅使用容器的一部分,通常使用迭代器定义的任何序列的明显原因):

模板
std::string convert2Str(先输入位,后输入位)
{
std::ostringstream sStream;
for(输入计算器it=first;it!=last;++it){

sStream他的第1点和你的第1点有什么区别。使用std::vector::const_迭代器不起作用,但类型定义起作用了吗?我感到困惑。他的解决方案只是在迭代器声明前面缺少一个类型名。(如编译器所述)但是为什么呢?这感觉像是c中一个在非typedefed类型前面缺少的结构。@Ronny:这里需要的是
typename
关键字。typedef只是用来简化到泛型容器的转换(仍然定义了
T
container
,但我切换了哪个是模板参数)。我猜行“typedef container::value_type T;//if needed”告诉编译器container是一个向量、列表等,并确保不能用简单的数据类型(如int或double)调用convert2Str。那么,为什么该语句标记为“if needed”…谢谢您的及时回答。@srikrish:这一行只会让您返回原始代码中存在的
T
类型。此函数没有在任何地方使用
T
,但我想告诉您如何访问它以防万一。即使没有这一行,如果您试图传入非容器的内容,编译器也会抱怨关于对
begin
end
的调用。如果T是用户定义的类型(我自己的类)当然,这实际上并没有教斯里克瑞什如何编写自己的泛型函数,这也是一项有用的技能。而且
ostream\u迭代器
使用C++0x会更好。@Ben:
decltype
令人困惑;看起来你在运行/计算一个表达式,而实际上你并没有。任何符合TL标准的容器将具有
值\u类型
(标准容器有,增压容器有,甚至Qt中的容器也有)@larsman:对不起,它真的应该是
ostream\u迭代器
。原始数组没有
值类型
,但它们确实与
std::begin
std::end
一起工作。而且它肯定应该是
使用std::copy;copy(…)
让Koenig查找完成它的工作。请记住,函数模板不能部分专用,并且禁止在
命名空间std
中定义新的重载,为容器提供优化版本的
copy
的唯一方法是使用ADL。*此代码可移植到solaris等平台吗?我最近使用了std::count在我的代码中,solaris中的sun编译器对此表示不满。您能解释一下“std::ostream_迭代器”这句话的含义吗做thanks@srikrish它适用于任何标准的符合C++编译器的,但是我不知道Sun编译器是否符合。参见.COD> > Type NeN/COD>。只需一个理由,就可以切换到C++ 0x ASAP。
template <typename Container>
std::string convert2Str(Container const &cont)
{
    std::ostringstream s;
    std::copy(cont.begin(), cont.end(),
              std::ostream_iterator<typename Container::value_type>(s, " "));
    return s.str();
}
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();
}
typedef typename std::iterator_traits<InputIterator>::value_type T;
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;