0

I give the following example to illustrate my question:

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

In the above codes, the function can deal with C++ container. I was wondering whether I can write a more general function can deal with simple variables in the meantime. For example:

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

      return 0;
  }

I tried to do it with this function, but failed:

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


  }
feelfree
  • 11,175
  • 20
  • 96
  • 167
  • 1
    You could perhaps use a custom type-trait like [the one shown in this old answer](http://stackoverflow.com/a/29634934/440558) in combination with [`std::enable_if`](http://en.cppreference.com/w/cpp/types/enable_if) for the compiler to select the function iterating over a collection, or another function just printing the value. – Some programmer dude Sep 23 '15 at 07:01

3 Answers3

1

Your second example won't compile, because there is no float::const_iterator type, or float::begin() method.

For templates like this, you want to use a C++ feature called SFINAE (subsitution failure is not an error), and type traits. You can find many sites / tutorials about it, for example this

Dutow
  • 5,638
  • 1
  • 30
  • 40
1

In your example, you can just add an overload (which is less specialized):

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

Jarod42
  • 203,559
  • 14
  • 181
  • 302
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;
}
Simon Kraemer
  • 5,700
  • 1
  • 19
  • 49