【问题标题】:template function for multiple containers and data types [duplicate]多个容器和数据类型的模板函数
【发布时间】:2013-02-25 22:18:00
【问题描述】:

我想创建一个模板函数,我可以将它用于不同的容器类型,如向量、双端队列或列表,我可以用不同的数据类型(整数、双精度或字符串)调用它,我已经搜索过但不能'找不到答案,我试过这样做,但我收到错误:

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <iterator>
#include <string>

using namespace std;
template <typename C>
void printvec(const C& numbers1)
//void printvec(container C<typename C::valuetype T>)
{
    //C &numbers1;
    for(auto i=0; i < numbers1.size(); ++i)
        cout<<&numbers1<<endl;
    //typename C<A>::iterator itr;
    //for ( itr=numbers1.begin();itr != numbers1.end(); ++itr)
      //  cout<<*itr<<endl;
}

int main()
{
    vector<int> vint{2,4,6,8,9,3};
    vector<double> vdouble{5.8, 6.7, 7.3};
    vector<string> vstring {"alex", "bbb", "cccc"};
    list<int> ls{1,2,3,4,5};
    printvec(vint );
    printvec(vdouble);
    printvec(vstring);
    printvec(ls);
        return 0;
}

请问,正确的做法是什么?

【问题讨论】:

  • This 可能会有帮助

标签: c++ templates stl c++11


【解决方案1】:

没有必要为此创建一个函数,标准库已经拥有你需要的所有工具:

 std::copy(vec.begin(),vec.end(),
     std::ostream_iterator(cout,"\n"));

如果您可以使用 C++11,请使用 std::begin(vec) 而不是 vec.begin()end 也是如此 - 正如@AndyProwl 正确指出的那样,它更通用。

【讨论】:

  • 我建议使用begin(vec)end(vec) 而不是成员函数,这样它也可以在C 风格的数组上工作
【解决方案2】:

其他人指出了为什么应该使用库函数以及为什么要重新发明轮子。如果你想这样做,你应该这样写。

容器不是根据抽象基类指定的,而是一个通用接口,它指定了所需的语法和语法结构的预期语义(这些东西称为概念)。最通用的是Container,更专业的是SequenceContainer。如果您接受 SequenceContainer 作为模板参数,则必须将使用模板参数的代码约束到这些要求。在你的情况下:

template<typename SequenceContainer>
void print(const SequenceContainer& seq)
{
  // being able to use range-for loops 
  // is a consequence of being a SequenceContainer
  for(auto& i : seq) {
    std::cout << i << " ";
  }
  std::cout << std::endl;

  // alternatively
  using std::begin; // enable ADL fallback for arrays
  using std::end;
  for(auto it = begin(seq); it != end(seq); ++it) {
    std::cout << *it << " ";
  }
  std::cout << std::endl;
}

编写好的模板代码不适合胆小的人,所以你可以 想考虑先更好地了解基本的 C++。

【讨论】:

    【解决方案3】:

    如果您真的需要编写自己的函数来迭代通用容器,那么这可能是适用于任何标准容器的最简单方法:

    template <typename C>
    void print(const C& c)
    {
        for (auto const& e : c) 
        { 
            cout << e << endl; 
        }
    }
    

    但是,正如us2012 正确指出的那样,没有必要重新发明轮子。

    【讨论】:

      【解决方案4】:

      这正是标准库有像for_each 这样的算法的原因。您传递一个开始和结束迭代器而不是容器本身。您作为第三个参数传递的模板化函数负责这项工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-03
        • 2010-09-15
        • 1970-01-01
        相关资源
        最近更新 更多