to read it?) I came across a discussion of using templates to "unroll"
loops. I thought that looked like a good idea, so I decided to try it on
some code I'm writing. The idea is to use template objects to perform what
happens in traditional nested for() loops.
for(int row = 0; row < num_rows; row++)
{
for(int col = 0; col < num_cols; col++)
{
operation(a1[row][col], a2[row][col]);
}
}
This code (I believe) accomplishes my objective for '==':
/* gnuBoilerplate. hh */
#ifndef _GNU_BOILERPLAT E_HH_
#define _GNU_BOILERPLAT E_HH_
/*************** *************** *************** *************** ***************
* Copyright (C) 2004 by Steven T. Hatton *
* ha*****@globals ymmetry.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
*************** *************** *************** *************** ***************/
#endif
/* Array2Equal.hh */
#ifndef STH_VMATH_ARRAY 2EQUAL_HH_
#define STH_VMATH_ARRAY 2EQUAL_HH_
#include "gnuBoilerplate .hh"
#include "ArrayEqual .hh"
namespace sth{
namespace vmath{
template <unsigned NUMBER_OF_ROWS, unsigned NUMBER_OF_COLUM NS, typename
T >
class Array2Equal{
public:
static bool equal(const T a1[][NUMBER_OF_COLUM NS], const T a2[
[NUMBER_OF_COLUM NS])
{
return ArrayEqual<NUMB ER_OF_COLUMNS, T>::equal(a1[NUMBER_OF_ROWS-1], a
[NUMBER_OF_ROWS-1])
&& Array2Equal<NUM BER_OF_ROWS - 1, NUMBER_OF_COLUM NS, T>::equal(a1, a2);
}
};
template <unsigned NUMBER_OF_COLUM NS, typename T >
class Array2Equal<1, NUMBER_OF_COLUM NS, T>{
public:
static bool equal(const T a1[][NUMBER_OF_COLUM NS], const T a2[
[NUMBER_OF_COLUM NS])
{
return ArrayEqual<NUMB ER_OF_COLUMNS, T>::equal(a1[0], a2[0]);
}
};
template<unsign ed NUMBER_OF_ROWS, unsigned NUMBER_OF_COLUM NS, typename
T >
inline bool equal2Array(con st T a1[][NUMBER_OF_COLUM NS], const T a2[
[NUMBER_OF_COLUM NS])
{
return Array2Equal<NUM BER_OF_ROWS, NUMBER_OF_COLUM NS, T >::equal(a1,
a2);
}
}
}
#endif
/* ArrayEqual.hh */
#ifndef ARRAYEQUAL_HH
#define ARRAYEQUAL_HH
#include "gnuBoilerplate .hh"
namespace sth{
namespace vmath{
template <unsigned NUMBER_OF_ELEME NTS, typename T>
class ArrayEqual{
public:
static bool equal(const T* a1, const T* a2)
{
return (*a2 == *a1)
&& ArrayEqual<NUMB ER_OF_ELEMENTS - 1, T>::equal(a1 + 1, a2 + 1);
}
};
template <typename T >
class ArrayEqual<1,T> {
public:
static bool equal(const T* a1, const T* a2)
{
return *a2 == *a1;
}
};
template <unsigned NUMBER_OF_ELEME NTS, typename T >
inline bool equalArray(cons t T* a1, const T* a2)
{
return ArrayEqual<NUMB ER_OF_ELEMENTS, T>::equal(a1, a2);
}
}
}
#endif
I tried very hard to pass a comparator function object as an additional
argument to the templates. For example I created
template <typename T>
struct Equal{
bool operator()(T a, T b) {return a==b;}
};
But no matter how I tried to use it, I kept getting errors saying there was
no funciton Equal(T a, T b);
This is an example:
#ifndef ARRAYCOMPARE_HH
#define ARRAYCOMPARE_HH
#include "gnuBoilerplate .hh"
#include <functional>
namespace sth{
namespace vmath{
template <typename T>
struct Equal: public std::binary_fun ction<bool,T,T>
{
bool operator()( T a, T b) const {return a == b;}
};
template <unsigned NUMBER_OF_ELEME NTS, typename T, typename COMPARATOR>
class ArrayCompare{
public:
static bool compare(const T* a1, const T* a2)
{
return COMPARATOR(*a2, *a1)
&& ArrayCompare<NU MBER_OF_ELEMENT S - 1, T, COMPARATOR>::co mpare(a1 + 1,
a2 + 1);
}
};
template <typename T, typename COMPARATOR >
class ArrayCompare<1, T, COMPARATOR>{
public:
static bool compare(const T* a1, const T* a2)
{
return COMPARATOR(*a2, *a1);
}
};
template <unsigned NUMBER_OF_ELEME NTS, typename T, typename COMPARATOR >
inline bool compareArray(co nst T* a1, const T* a2)
{
return ArrayCompare<NU MBER_OF_ELEMENT S, T, COMPARATOR>::co mpare(a1,
a2);
}
}
}
#endif
/* Array2Compare.h h */
#ifndef STH_VMATH_ARRAY 2COMPARE_HH_
#define STH_VMATH_ARRAY 2COMPARE_HH_
#include "gnuBoilerplate .hh"
#include "ArrayCompare.h h"
#include <functional>
namespace sth{
namespace vmath{
template <unsigned NUMBER_OF_ROWS, unsigned NUMBER_OF_COLUM NS, typename
T, typename COMPARATOR >
class Array2Compare{
public:
static bool compare(const T a1[][NUMBER_OF_COLUM NS], const T a2[
[NUMBER_OF_COLUM NS])
{
return ArrayCompare<NU MBER_OF_COLUMNS , T, COMPARATOR>::co mpare(a
[NUMBER_OF_ROWS-1], a2[NUMBER_OF_ROWS-1])
&& Array2Compare<N UMBER_OF_ROWS - 1, NUMBER_OF_COLUM NS, T,
COMPARATOR>::co mpare(a1, a2);
}
};
template <unsigned NUMBER_OF_COLUM NS, typename T, typename COMPARATOR >
class Array2Compare<1 , NUMBER_OF_COLUM NS, T, COMPARATOR>{
public:
static bool compare(const T a1[][NUMBER_OF_COLUM NS], const T a2[
[NUMBER_OF_COLUM NS])
{
return ArrayCompare<NU MBER_OF_COLUMNS , T, COMPARATOR>::co mpare(a1[0], a
[0]);
}
};
template<unsign ed NUMBER_OF_ROWS, unsigned NUMBER_OF_COLUM NS, typename
T, typename COMPARATOR >
inline bool compare2Array(c onst T a1[][NUMBER_OF_COLUM NS], const T a2[
[NUMBER_OF_COLUM NS])
{
return Array2Compare<N UMBER_OF_ROWS, NUMBER_OF_COLUM NS, T, COMPARATOR
::compare(a1 , a2); }
}
}
#endif
/* main.cc */
#include "gnuBoilerplate .hh"
#include <sth/vmath/Array2Compare.h h>
#include <iostream>
using sth::vmath::com pare2Array;
using sth::vmath::Equ al;
using std::cout;
using std::boolalpha;
using std::noboolalph a;
main()
{
float a1[3][3] = {{1,2,3},{4,5,6 },{7,8,9}};
float b1[3][3] = {{10,20,30},{40 ,50,60},{70,80, 90}};
cout
<< boolalpha
<< "compare2Array( a1,b1): " << compare2Array<3 ,3,float,Equal< float>(a1,b1) << "\n"
<< noboolalpha;
return 0;
}
//EOF
Wed Oct 06 15:05:53:> g++ -o compare main.cc -I/home/hattons/code/c++
/home/hattons/code/c++/sth/vmath/ArrayCompare.hh :20: error: no matching
function for call to `sth::vmath::Eq ual<float>::Equ al(const float&, const
float&)'
/home/hattons/code/c++/sth/vmath/ArrayCompare.hh :11: error: candidates are:
sth::vmath::Equ al<float>::Equa l()
/home/hattons/code/c++/sth/vmath/ArrayCompare.hh :11: error:
sth::vmath::Equ al<float>::Equa l(const sth::vmath::Equ al<float>&)
Suggestions?
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell