我可以在此期间编写一个可以处理容器和简单变量的模板函数吗?

时间:2015-09-23 06:53:29

标签: c++

我举了以下例子来说明我的问题:

  template<typename T>
  void write_numerical_array(const std::vector<T> &nArray)
  {
      typename std::vector<T>::const_iterator it = nArray.begin();
      while(it!=nArray.end())
      {
          std::cout<<*it<<std::endl;
          it++;
      }


  }
 int main(int,char*[])
  {

      std::vector<int> nArray;
      for(int i=0; i<10; i++)
          nArray.push_back(i);

    write_numerical_array ( nArray);
    return 0;
}

在上面的代码中,该函数可以处理C ++容器。我想知道我是否可以编写更通用的函数来同时处理简单变量。例如:

 int main(int,char*[])
  {
      float value =100;
      write_numerical_array(value);

      return 0;
  }

我尝试使用此功能,但失败了:

 template<typename T>
  void write_numerical_array(T &nArray)
  {
      typename T::const_iterator it = nArray.begin();
      while(it!=nArray.end())
      {
          std::cout<<*it<<std::endl;
          it++;
      }


  }

3 个答案:

答案 0 :(得分:1)

您的第二个示例无法编译,因为没有float::const_iterator类型或float::begin()方法。

对于这样的模板,您希望使用名为SFINAE的C ++功能(替换失败不是错误),并键入traits。您可以找到许多有关它的网站/教程,例如this

答案 1 :(得分:1)

在您的示例中,您只需添加一个重载(不太专业化):

template<typename T>
void write_numerical(const std::vector<T>& v)
{
    for (const auto &e : v) {
        std::cout << e << std::endl;
    }
}

template<typename T>
void write_numerical(const T &e)
{
    std::cout << e << std::endl;
}

Live Demo

答案 2 :(得分:1)

#include <iostream>
#include <vector>
#include <array>

template <typename T>
struct has_const_iterator
{
private:
    typedef char yes[1];
    typedef char no[2];

    template <typename T>
    static yes& test(typename T::const_iterator*);

    template <typename>
    static no& test(...);

public:
    static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};



template <typename T>
void do_write_numerical_array(typename std::enable_if<has_const_iterator<T>::value, const T>::type &v) {
    std::cout << "Container" << std::endl;
    for (const auto &e : v) {
        std::cout << e << std::endl;
    }
}

template <typename T>
void do_write_numerical_array(typename std::enable_if<!has_const_iterator<T>::value, const T>::type &e) {
    std::cout << "Simpel" << std::endl;
    std::cout << e << std::endl;
}


template <typename T>
inline void write_numerical_array(const T &t) {
    do_write_numerical_array<T>(t);
}

int main(int, char*[])
{
    bool b = has_const_iterator<std::vector<int>>::value;
    std::vector<int> nArray;
    for (int i = 0; i<10; i++)
        nArray.push_back(i);
    write_numerical_array(nArray);
    write_numerical_array(1.0);
    write_numerical_array(1.0f);
    write_numerical_array("saff");
    write_numerical_array(std::array<double, 4>{ 1,2,3,4 });
    return 0;
}