【问题标题】:Can I write a template function that can deal with container and simple variable in the meantime?我可以同时编写一个可以处理容器和简单变量的模板函数吗?
【发布时间】:2015-12-20 09:03:03
【问题描述】:

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

  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++;
      }


  }

【问题讨论】:

标签: c++


【解决方案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】:

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

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

    【讨论】:

      【解决方案3】:
      #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;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-08-04
        • 2019-10-29
        • 2013-12-08
        • 1970-01-01
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多