编写通用打印函数以打印数组

时间:2018-12-26 07:18:04

标签: c++ arrays generics printing

我想在这里问两个问题:

  1. 要创建一个通用打印功能,该功能可以打印任何数据类型(例如int,char,string等)的数组(或向量)
  2. 要创建一个打印函数,该函数需要输入一个类的对象的对象数组(或矢量),并调用该类的打印函数(已经存在于类定义中)以打印每个对象的内容。

在Zillingo的安置面试中有人问我这个问题。面试官首先问我问题1,但经过我的一次很糟糕的尝试,他进一步使问题复杂化并问了问题2。

我对问题1提出的解决方案是,我将创建一个 Print 类,该类具有多个名为 print 的函数,但每个函数都将一个不同数据类型的数组作为参数(每个现有数据类型一个函数)。那之后我完全空白了。:(

2 个答案:

答案 0 :(得分:2)

您可以将模板功能用作

#include <iostream>
#include <vector>
using namespace std;

template <class InputIterator>
void print(InputIterator start,InputIterator end)
{
    for(auto itr=start;itr!=end;++itr)
    {
        cout<<*itr<<" ";
    }
    cout<<endl;
}

int main() {
    int arr[]={1,2,3,4,5};
    print(std::begin(arr),std::end(arr));
    vector<int> in={1,2,6,7};
    print(in.begin(),in.end());
    return 0;
}

答案 1 :(得分:1)

对于1,它看起来像:

namespace printing {
  template<class T>
  void print(std::ostream& os, T const& t){
    os<<t;
  }
  template<class It>
  void print_range( std::ostream& os, It b, It e );

  template<class T,std::size_t N>
  void print( std::ostream& os, T const(&arr)[N] ){
    print_range(os, std::begin(arr), std::end(arr) );
  }

  template<class T,std::size_t N>
  void print( std::ostream& os, std::array<T, N> const& arr ){
    print_range(os, std::begin(arr), std::end(arr) );
  }
  template<class T, class A>
  void print( std::ostream& os, std::vector<T, A> const& arr ){
    print_range(os, std::begin(arr), std::end(arr) );
  }
  // etc

  template<class It>
  void print_range( std::ostream& os, It b, It e ){
    for(auto it=b; it!=e; ++it)
      print(os, *it);
  }
}

现在,要进行改进,请添加SFINAE可迭代性检测,而不是单个重载。

对于2,为指针和实例类型(通过decltype和.print(std::ostream&)->)写.方法的SFINAE检测。然后编写仅适用于print->print型的.print重载,并使其比os<<t;版本更好,但比任何{{1 }}类型的名称空间中的自由函数。

正确执行需要花几十行样板,并且我想在实际的编译器中测试几次重载顺序。最后,print函数可能不会被称为os<<t或不在非详细名称空间中。