C++/Function/Function Template

Материал из C\C++ эксперт
Перейти к: навигация, поиск

A generic mode finding function.

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

template <class X> X mode(X *data, int size)
{
  register int t, w;
  X md, oldmd;
  int count, oldcount;
  oldmd = 0;
  oldcount = 0;
  for(t=0; t<size; t++) {
    md = data[t];
    count = 1;
    for(w = t+1; w < size; w++) 
      if(md==data[w]) count++;
    if(count > oldcount) {
      oldmd = md;
      oldcount = count;
    }
  }
  return oldmd;
}
int main()
{
  int i[] = { 1, 2, 3, 4, 2, 3, 2, 2, 1, 5};
  char *p = "this is a test";
  cout << "mode of i: " << mode(i, 10) << endl;
  cout << "mode of p: " << mode(p, (int) strlen(p));
  return 0;
}


Creating a custom algorithm based on template

 
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
template<class ForIter>
  void times2(ForIter start, ForIter end)
{
  while(start != end) {
    *start *= 2;
    start++;
  }
}
int main()
{
  int i;
  vector<int> vectorObject;
  for(i = 0; i <10; i++) 
     vectorObject.push_back(i);
  cout << "Initial Contents of vectorObject: ";
  for(i = 0; i <vectorObject.size(); i++)
    cout << vectorObject[ i ] << " ";
  cout << endl;
  times2(vectorObject.begin(), vectorObject.end());
  cout << "Contents of vectorObject doubled: ";
  for(i = 0; i <vectorObject.size(); i++)
    cout << vectorObject[ i ] << " ";
  cout << endl;
  list<float> lst;
  list<float>::iterator p;
  for(i = 0; i <5; i++) 
     lst.push_back((float)i*3.1416);
  cout << "Initial Contents of lst: ";
  for(p=lst.begin(); p!=lst.end(); p++)
    cout << *p << " ";
  cout << endl;
  times2(lst.begin(), lst.end());
  cout << "Contents of lst doubled: ";
  for(p=lst.begin(); p!=lst.end(); p++)
    cout << *p << " ";
  cout << endl;
  return 0;
}


find all template function

  
#include <vector>
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
template <typename InputIterator, typename Predicate>
vector<InputIterator> find_all(InputIterator first, InputIterator last, Predicate pred)
{
  vector<InputIterator> res;
  while (true) {
    first = find_if(first, last, pred);
    if (first == last) {
      break;
    }
    res.push_back(first);
    ++first;
  }
  return (res);
}
int main(int argc, char** argv){
  int arr[] = {3, 4, 5, 4, 5, 6, 5, 8};
  vector<int*> all = find_all(arr, arr + 8, bind2nd(equal_to<int>(), 5)); 
  
  cout << "Found " << all.size() << " matching elements: ";
  
  for (vector<int*>::iterator it = all.begin(); it != all.end(); ++it) {
    cout << **it << " ";
  }
  return (0);
}


function template for getting the max value

  
#include <iostream>
using namespace std;
template <class T>
T GetMax (T a, T b) {
  return (a>b?a:b);
}
int main () {
  int i=5, j=6, k;
  long l=10, m=5, n;
  k=GetMax(i,j);
  n=GetMax(l,m);
  cout << k << endl;
  cout << n << endl;
  return 0;
}


Function template: swap values

 

#include <iostream>
using namespace std;
template <class X> void swapargs(X &a, X &b)
{
  X temp;
  temp = a;
  a = b;
  b = temp;
}
int main()
{
  int i=10, j=20;
  float x=10.1, y=23.3;
  cout << "Original i, j: " << i << " " << j << endl;
  cout << "Original x, y: " << x << " " << y << endl;
  swapargs(i, j); // swap integers
  swapargs(x, y); // swap floats
  cout << "Swapped i, j: " << i << " " << j << endl;
  cout << "Swapped x, y: " << x << " " << y << endl;
  return 0;
}


Making a Sequence of Random Numbers

  
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <vector>
#include <iostream>
using namespace std;
template <class T>
void print(T& c){
   for( typename T::iterator i = c.begin(); i != c.end(); i++ ){
      std::cout << *i << endl;
   }
}
int main( )
{
   vector<int> random( 8 );
   // fill the container with random numbers
   generate( random.begin(), random.end(), rand );
   print( random );
}


Overriding a template function.

   
#include <iostream>
using namespace std;
   
template <class X> void swapargs(X &a, X &b)
{
  X temp;
   
  temp = a;
  a = b;
  b = temp;
  cout << "Inside template swapargs.\n";
}
   
// This overrides the generic version of swapargs() for ints.
void swapargs(int &a, int &b)
{
  int temp;
   
  temp = a;
  a = b;
  b = temp;
  cout << "Inside swapargs int specialization.\n";
}
   
int main()
{
  int i=10, j=20;
  double x=10.1, y=23.3;
  char a="x", b="z";
   
  cout << "Original i, j: " << i << " " << j << "\n";
  cout << "Original x, y: " << x << " " << y << "\n";
  cout << "Original a, b: " << a << " " << b << "\n";
   
  swapargs(i, j); // calls explicitly overloaded swapargs()
  swapargs(x, y); // calls generic swapargs()
  swapargs(a, b); // calls generic swapargs()
   
  cout << "Swapped i, j: " << i << " " << j << "\n";
  cout << "Swapped x, y: " << x << " " << y << "\n";
  cout << "Swapped a, b: " << a << " " << b << "\n";
   
  return 0;
}


Simple template function to accept two parameters

 
#include <iostream>
using namespace std;
template <class type1, class type2>
void myFunction(type1 x, type2 y)
{
  cout << x << " " << y << endl;
}
int main()
{
  myFunction(10, "hi");
  myFunction(0.23, 10L);
  return 0;
}


Template copy array function

  
#include <iostream>
using namespace std;
template<class TYPE>
void copy(TYPE a[], TYPE b[], int n)
{
   for (int i = 0; i < n; ++i)
      a[i] = b[i];
}
template<class TYPE>
void print(TYPE a[], int n)
{
   cout << "\nNEW PRINT =";
   for (int i = 0; i < n; ++i)
      cout << a[i] << " ";
}
int main()
{
   double  f1[50], f2[50];
   char    c1[25], c2[50];
   int     i1[75], i2[75];
   int     i;
   for (i = 0; i < 50; ++i) { //init arrays
      f1[i] = 1.1 + i;
      f2[i] = 2.2 * i;
      c2[i] = "A" + i/5;
   }
   for (i = 0; i < 25; ++i) { //init arrays
      c1[i] = "a" + i/8;
   }
   for (i = 0; i < 75; ++i) { //init arrays
      i1[i] = 2 * i;
      i2[i] = i * i;
   }
   print(f1, 20);    //print initial values
   print(f2, 20);
   print(i1, 20);
   print(i2, 20);
   print(c1, 20);
   print(c2, 20);
   copy(f1, f2, 50);
   copy(c1, c2, 10);
   copy(i1, i2, 40);
   print(f1, 20);    //print initial values
   print(f2, 20);
   print(i1, 20);
   print(i2, 20);
   print(c1, 20);
   print(c2, 20);
}


template function for bubble sort

  
#include <iostream>
using namespace std;
template <class X> void bubble_sort(X *items, int size);
template <class X> void show_items(X *items, int size);
int main(void)
{
   int iarray[7] =      {7, 5, 4, 3, 9, 8, 6};
   double darray[5] =   {4.2, 2.5, -0.9, 1.2, 3.0};
   cout << "Here is unsorted integer array: " << endl;
   show_items(iarray, 7);
   cout << "Here is unsorted double array: " << endl;
   show_items(darray, 5);
   bubble_sort(iarray, 7);
   bubble_sort(darray, 5);
   cout << "Here is sorted integer array: " << endl;
   show_items(iarray, 7);
   cout << "Here is sorted double array: " << endl;
   show_items(darray, 5);
}
template <class X> void bubble_sort(X *items, int size)
{
   register int i, j;
   X temp;
   for (i = 1; i < size; i++)
    for (j = size-1; j >= i; j--)
      if (items[j-1] > items[j])
        {
          temp = items[j-1];
          items[j-1] = items[j];
          items[j] = temp;
        }
}
template <class X> void show_items(X *items, int size)
{
   int i;
   for(i=0; i < size; i++)
      cout << items[i] << ", ";
   cout << endl;
}


template function for compacting the items

  
#include <iostream>
using namespace std;
template <class X> void compact(X *items, int count, int start, int end);
template <class X> void show_items(X *items, int size);
int main(void)
{
   int nums[7] =  {0, 1, 2, 3, 4, 5, 6};
   char str[18] = "Generic Functions";
   cout << "Here is uncompacted integer array: ";
   show_items(nums, 7);
   cout << "Here is the uncompacted char array: ";
   show_items(str, 18);
   compact(nums, 7, 2, 4);
   compact(str, 18, 6, 10);
   cout << "Here is compacted integer array: ";
   show_items(nums, 7);
   cout << "Here is the compacted char array: ";
   show_items(str, 18);
}
template <class X> void compact(X *items, int count, int start, int end)
{
   register int i;
   for(i=end+i; i < count; i++, start++)
      items[start] = items[i];
   for( ; start<count; start++)
      items[start] = (X) 0;
}
template <class X> void show_items(X *items, int size){
   int i;
   for(i=0; i < size; i++)
      cout << items[i];
   cout << endl;
}


template function for find a value

 
#include <iostream>
#include <cstring>
using namespace std;
template <class X> int find(X object, X *list, int size)
{
  int i;
  for(i = 0; i <size; i++)
    if(object == list[ i ]) 
       return i;
  return -1;
}
int main()
{
  int a[] = {1, 2, 3, 4};
  char *c = "this is a test";
  double d[] = {1.1, 2.2, 3.3};
  cout << find(3, a, 4);
  cout << endl;
  cout << find("a", c, (int) strlen(c));
  cout << endl;
  cout << find(0.0, d, 3);
  return 0;
}


Use a Function Object to Hold state

  
#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
using namespace std;
template <typename elementType>
struct DisplayCounter
{
    int m_nCount;
    DisplayCounter ()
    {
        m_nCount = 0;
    }
    // Display the element, hold count!
    void operator () (const elementType& element)
    {
        ++ m_nCount;
        cout << element << " ";
    }
};
int main ()
{
    vector <int> v;
    for (int nCount = 0; nCount < 10; ++ nCount)
        v.push_back (nCount);
    DisplayCounter <int> mResult;
    mResult = for_each ( v.begin (), v.end (), DisplayCounter <int> () );
    cout << """ << mResult.m_nCount << "" elements were displayed!" << endl;
    return 0;
}


Using a Binary Function to Multiply Two Ranges

  
#include <vector>
#include <iostream>
#include <algorithm>
template <typename elementType>
class CMultiply
{
public:
    elementType operator () (const elementType& elem1,const elementType& elem2){
        return (elem1 * elem2);
    }
};
int main (){
    using namespace std;
    vector <int> v1, v2, vecResult;
    for (int nCount1 = 0; nCount1 < 10; ++ nCount1)
        v1.push_back (nCount1);
    for (int nCount2 = 100; nCount2 < 110; ++ nCount2)
        v2.push_back (nCount2);
    vecResult.resize (10);
    transform ( v1.begin(), 
                v1.end(), 
                v2.begin(),  // multiplier values
                vecResult.begin(),      // range that holds result
                CMultiply <int>() );    // the function that multiplies
    for (size_t nIndex1 = 0; nIndex1 < v1.size (); ++ nIndex1)
        cout << v1 [nIndex1] << " ";
    for (size_t nIndex2 = 0; nIndex2 < v2.size (); ++nIndex2)
        cout << v2 [nIndex2] << " ";
    for (size_t nIndex = 0; nIndex < vecResult.size (); ++ nIndex)
        cout << vecResult [nIndex] << " ";
    return 0;
}


Using Standard Parameters with Template Functions

   
#include <iostream>
using namespace std;
   
const int TABWIDTH = 8;
   
// Display data at specified tab position.
template<class X> void tabOut(X data, int tab)
{
  for(; tab; tab--)
    for(int i=0; i<TABWIDTH; i++) cout << " ";
   
    cout << data << "\n";
}
   
int main()
{
  tabOut("This is a test", 0);
  tabOut(100, 1);
  tabOut("X", 2);
  tabOut(10/3, 3);
   
  return 0;
}


write function object

  
#include <functional>
#include <algorithm>
#include <cctype>
#include <string>
#include <iostream>
using namespace std;
class myIsDigit : public unary_function<char, bool>{
public:
  bool operator() (char c) const { return (::isdigit(c)); }
};
bool isNumber(const string& str){
  string::const_iterator it = find_if(str.begin(), str.end(),not1(myIsDigit()));
  return (it == str.end());
}
int main(int argc, char** argv){
  cout << isNumber("12345") << endl;
  cout << isNumber("hello") << endl;
  cout << isNumber("1234a") << endl;
  return (0);
}