473,769 Members | 2,348 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Comparator template argument in recursive templates?

While thunbing through _C++ Templates, The Complete Guide_ (reckon I aught
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

Jul 22 '05 #1
2 2014

"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote in message
news:N-*************** *****@speakeasy .net...
While thunbing through _C++ Templates, The Complete Guide_ (reckon I aught
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]);
}
}
[snip]
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);

I think its a simple error (but haven't tried compiling anything). I think
you are mixing object with type.

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)


COMPARATOR is a type, so you must construct an object and then call your
operator(), i.e.

return COMPARATOR()(*a 2, *a1)

john
Jul 22 '05 #2
John Harrison wrote:
COMPARATOR is a type, so you must construct an object and then call your
operator(), i.e.

return COMPARATOR()(*a 2, *a1)
Wow! That is SO obvious (in retrospect). I should have caught it. Thanks!

This compiles and runs, producing the expected results. I still need to
think it all through. I believe it may be traversing backwards. That's
fine for symmetrical operations, but if I want a lexicographic comparrison,
it would not perform as expected.

I did catch another stupid mistake while fixing the one you pointed out. I
now only have one call to COMPARATOR cmp; return cmp(*a2, *a1);

/* ArrayCompare.hh */
#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 ArrayCompare<1, T,COMPARATOR>:: compare(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)
{
COMPARATOR cmp;
return cmp(*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 "ArrayCompare.h h"
#include "gnuBoilerplate .hh"

#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/ArrayCompare.hh >
#include <sth/vmath/Array2Compare.h h>
#include <iostream>

using sth::vmath::com pareArray;
using sth::vmath::com pare2Array;
using sth::vmath::Equ al;

using std::cout;
using std::boolalpha;
using std::noboolalph a;
int main()
{

float a[3] = {1,2,3};
float b[3] = {10,20,30};
Equal<float> ef;
cout
<< boolalpha
<< "compareArray(a ,b): " << compareArray<3, float, Equal<float> >(a,b) <<
"\n"
<< noboolalpha;
float a1[3][3] = {{1,2,3},{4,5,6 },{7,8,9}};
float a2[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" << "compare2Array( a1,a2): " << compare2Array<3 ,3,float,Equal< float>(a1,a2) << "\n"

<< noboolalpha;

return 0;
}
/* gnuBoilerplate. hh */

#ifndef _GNU_BOILERPLAT E_HH_
#define _GNU_BOILERPLAT E_HH_
/*************** *************** *************** *************** ***************
*****Copyright* (C)*2004*by*Ste ven*T.*Hatton** *************** *************** *
*****ha*****@gl obalsymmetry.co m************** *************** *************** *
*************** *************** *************** *************** *************** *
*****This*progr am*is*free*soft ware;*you*can*r edistribute*it* and/or*modify***
*****it*under*t he*terms*of*the *GNU*General*Pu blic*License*as *published*by** *
*****the*Free*S oftware*Foundat ion;*either*ver sion*2*of*the*L icense,*or***** *
*****(at*your*o ption)*any*late r*version.***** *************** *************** *
*************** *************** *************** *************** *************** *
*****This*progr am*is*distribut ed*in*the*hope* that*it*will*be *useful,******* *
*****but*WITHOU T*ANY*WARRANTY; *without*even*t he*implied*warr anty*of******** *
*****MERCHANTAB ILITY*or*FITNES S*FOR*A*PARTICU LAR*PURPOSE.**S ee*the********* *
*****GNU*Genera l*Public*Licens e*for*more*deta ils.*********** *************** *
*************** *************** *************** *************** *************** *
*****You*should *have*received* a*copy*of*the*G NU*General*Publ ic*License***** *
*****along*with *this*program;* if*not,*write*t o*the********** *************** *
*****Free*Softw are*Foundation, *Inc.,********* *************** *************** *
*****59*Temple* Place*-*Suite*330,*Bos ton,*MA**02111-1307,*USA.***** *********
*************** *************** *************** *************** *************** */
#endif

Now I need to generalize the code for n dimensional arrays...
--
"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

Jul 22 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
6191
by: wogston | last post by:
A) template <typename scalar, int size> struct basevector { enum { size = size }; scalar v; }; B)
7
2511
by: Rolf Kemper | last post by:
Dear All, somehow I remember that such or similar question was discussed already somewhere. But I can't find it anymore. I have a template calling itself. As long it goes deeper into the hierarchy (by the key) I can set the CurrentY parameter by itself + some constant correctly. Hence which each call the CurrentY gets bigger. But when the template reaches a leave and the caller is poped from
5
1724
by: Mohammad | last post by:
Hi, Is it possible to disable a method of a template class depending on the typename at compile time? thanks!
6
1583
by: Hendrik Schober | last post by:
Hi, I have a problem with extending some existing code. In a simplified form, the problem looks like this: I have four types, A, B, C, and D. Each A refers to zero, one, or more B's and each B can be child to zero, one, or more A's. I just call that "A is a parent of B", and "B is a child of A". The same goes for B and C and for C and D. So A is only a parent, B and C are both parents and children, and D is only a child.
6
1831
by: Neal | last post by:
Hi All, I used an article on XSLT and XML and creating a TOC written on the MSDN CodeCorner. ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/dncodecorn/html/corner042699.htm However, it did'nt quite answer all my questions. How would one create a 3 level TOC when each item level / node was differently named (They used Template match and for-each, but the template match worked as on a 3 level structure they usedf the same named xml...
5
3369
by: Mark Stijnman | last post by:
I am trying to teach myself template metaprogramming and I have been trying to create lists of related types. I am however stuck when I want to make a template that gives me the last type in a list. I started by using a linked list of types with templates like: struct MyClass1 {}; struct MyClass2 {}; struct MyClass3 {}; struct NullType {};
19
2565
by: n.torrey.pines | last post by:
I have the following tree definition: template<typename T> struct tree { T first; vector<tree<T second; // branches }; which compiles successfully. What I'd like to do though is to use another template like 'pair', because I might have a bunch of useful
8
284
by: William Xu | last post by:
Compiling: template <class T = int> T foo(const T& t) {} int main(int argc, char *argv) {} gcc complains:
2
6645
by: Clyde | last post by:
Hi, what i'm trying to do is: /////////////// Code Start template <class TType, int* p = 0> class Template { public:
0
10043
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9990
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9861
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8869
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7406
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6672
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5298
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5446
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2814
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.