Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template function type for arithmetic operators for elementary types

Reply
Thread Tools

Template function type for arithmetic operators for elementary types

 
 
Lionel B
Guest
Posts: n/a
 
      03-02-2005
Greetings,

I am trying to implement "element-wise" arithmetic operators for a class
along the following lines (this is a simplified example):

// ----- BEGIN CODE -----

struct X
{
int a,b;

typedef int& optype(int&,int); // ???

template<optype OP> void element_wise(X& x)
{
OP(a,x.a);
OP(b,x.b);
}

X& operator+=(X& x)
{
element_wise< :perator+=<int> >(x); // ??? (line 15)
return *this;
}
};

int main()
{
X x,y;

x.a = 1;
x.b = 2;
y.a = 3;
y.b = 4;

x += y;

return 0;
}

// ----- END CODE -----

I get the error (gcc):

test.cpp: In member function `X& X:perator+=(X&)':
test.cpp:15: error: no matching function for call to
`X::element_wise(X&)'

This is perhaps not surprising, in view of that:

// ----- BEGIN CODE -----

int main()
{
int a = 1;

operator += (a,1);

return 0;
}


// ----- END CODE -----

fails to compile with "error: `operator+=' not defined" (this surprised
me somewhat). It seems that function-style prototypes for arithmetic
operators on elementary types don't exist.

So is it at all possible to use arithmetic operators for elementary
types as template arguments? A simple workaround is to wrap the
operators in a function, but it would be neater (and conceivably more
efficient) not to have to do this.

Regards,

--
Lionel B


 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      03-02-2005
Lionel B wrote:
> [...]
> So is it at all possible to use arithmetic operators for elementary
> types as template arguments? A simple workaround is to wrap the
> operators in a function, but it would be neater (and conceivably more
> efficient) not to have to do this.


Take a look at the library implementation of 'std:lus' and other
arithmetic functors. They are defined in <functional> and described
in 20.3.2. My guess is you should simply use them and/or provide your
own of similar form.

V
 
Reply With Quote
 
 
 
 
Gianni Mariani
Guest
Posts: n/a
 
      03-02-2005
Lionel B wrote:
> Greetings,
>
> I am trying to implement "element-wise" arithmetic operators for a class
> along the following lines (this is a simplified example):
>
> // ----- BEGIN CODE -----
>
> struct X
> {
> int a,b;
>
> typedef int& optype(int&,int); // ???
>
> template<optype OP> void element_wise(X& x)
> {
> OP(a,x.a);
> OP(b,x.b);
> }
>
> X& operator+=(X& x)
> {
> element_wise< :perator+=<int> >(x); // ??? (line 15)
> return *this;
> }
> };


Not all compilers will support this yet because of the template-template
parameter. This compiled on GCC 4.0(snapshot).

template < template <typename Tf> class F, typename T >
void Do( T & res, const T& val )
{
F<T>:oThing( res, val );
}




template <typename Tf>
struct PlusEqual
{
static void DoThing( Tf & res, const Tf & val )
{
res += val;
}
};


template <typename Tf>
struct MinusEqual
{
static void DoThing( Tf & res, const Tf & val )
{
res -= val;
}
};


struct X
{
float a;
int b;


template < template <typename Tf> class F >
void ElementWise( const X & rhs )
{
Do<F>( a, rhs.a );
Do<F>( b, rhs.b );
}


X& operator+=( const X& rhs )
{
ElementWise<PlusEqual>( rhs );
return * this;
}


X& operator-=( const X& rhs )
{
ElementWise<PlusEqual>( rhs );
return * this;
}
};

I don't know how useful this is since it's limited in utility, however I
think that does what you were trying to do. In the example you posted,
there were numerous issues, I won't go into the details other than to
say, you can't pass a function as a template parameter in your case
since you don't know what the type of the parameters are, hence you can
pass a template as the template parameter.

>
> int main()
> {
> X x,y;
>
> x.a = 1;
> x.b = 2;
> y.a = 3;
> y.b = 4;
>
> x += y;
>
> return 0;
> }


This should now compile.

....

> // ----- BEGIN CODE -----
>
> int main()
> {
> int a = 1;
>
> operator += (a,1);


You're invoking global operator += on two ints:

"ComeauTest.c", line 1: error: nonmember operator requires a parameter
with class
or enum type
int operator +=( int &, int );

You can't override the built-in global operators, but you can create
your own types and define new global operators.

>
> return 0;
> }
>
>
> // ----- END CODE -----
>
> fails to compile with "error: `operator+=' not defined" (this surprised
> me somewhat). It seems that function-style prototypes for arithmetic
> operators on elementary types don't exist.
>
> So is it at all possible to use arithmetic operators for elementary
> types as template arguments? A simple workaround is to wrap the
> operators in a function, but it would be neater (and conceivably more
> efficient) not to have to do this.


Most compilers I have used will optimize the function calls away and the
efficiency become a non-issue.


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      03-02-2005
Gianni Mariani wrote:

Correction:

....
>
> template <typename Tf>
> struct MinusEqual
> {
> static void DoThing( Tf & res, const Tf & val )
> {
> res -= val;
> }
> };
>
>
> struct X
> {
> float a;
> int b;


....

>
>
> X& operator-=( const X& rhs )
> {
> ElementWise<PlusEqual>( rhs );


Should be:
ElementWise<MinusEqual>( rhs );

> return * this;
> }
> };

 
Reply With Quote
 
Lionel B
Guest
Posts: n/a
 
      03-02-2005
"Gianni Mariani" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Lionel B wrote:
> > Greetings,
> >
> > I am trying to implement "element-wise" arithmetic operators for a

class
> > along the following lines (this is a simplified example):
> >
> > // ----- BEGIN CODE -----
> >
> > struct X
> > {
> > int a,b;
> >
> > typedef int& optype(int&,int); // ???
> >
> > template<optype OP> void element_wise(X& x)
> > {
> > OP(a,x.a);
> > OP(b,x.b);
> > }
> >
> > X& operator+=(X& x)
> > {
> > element_wise< :perator+=<int> >(x); // ??? (line 15)
> > return *this;
> > }
> > };

>
> Not all compilers will support this yet because of the

template-template
> parameter. This compiled on GCC 4.0(snapshot).
>
> /snip code/


Cheers, yes that works for my gcc 3.3.3 too.

> I don't know how useful this is since it's limited in utility, however

I
> think that does what you were trying to do.


It does. BTW, the reason for what I was trying to do is simply to avoid
code duplication: my "real" ElementWise() function is rather lengthy and
complex, and needs to be parametrised by operator type (plus, minus,
etc.).

I suspect the "functional" approach you give above is probably
uneccessarily sophisticated for my needs... the following works
perfectly well for me.

typedef void optype(int&, const int&);

void plus_equal(int& a, int b)
{
a += b;
}

struct X
{
int a,b;

template<optype OP> void element_wise(X& x)
{
OP(a,x.a);
OP(b,x.b);
}

X& operator+=(X& x)
{
element_wise<plus_equal>(x);
return *this;
}
};

> In the example you posted,
> there were numerous issues, I won't go into the details other than to
> say, you can't pass a function as a template parameter in your case
> since you don't know what the type of the parameters are


Not sure I follow you... I *do* know the parameter types of the function
I want to pass as template parameter: namely (int&, const int), as
above. My issue was whether I could pass the global operator+= function
as a parameter to my to element_wise() ...

> /snip/


> > // ----- BEGIN CODE -----
> >
> > int main()
> > {
> > int a = 1;
> >
> > operator += (a,1);

>
> You're invoking global operator += on two ints:
>
> "ComeauTest.c", line 1: error: nonmember operator requires a parameter
> with class
> or enum type
> int operator +=( int &, int );
>
> You can't override the built-in global operators, but you can create
> your own types and define new global operators.


Yup - that's my solution above.

> > So is it at all possible to use arithmetic operators for elementary
> > types as template arguments?


So... no.

> > A simple workaround is to wrap the
> > operators in a function, but it would be neater (and conceivably

more
> > efficient) not to have to do this.

>
> Most compilers I have used will optimize the function calls away and

the
> efficiency become a non-issue.


No doubt.

Thanks,


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      03-03-2005
Lionel B wrote:

....
> I
>
>>think that does what you were trying to do.

>
>
> It does. BTW, the reason for what I was trying to do is simply to avoid
> code duplication: my "real" ElementWise() function is rather lengthy and
> complex, and needs to be parametrised by operator type (plus, minus,
> etc.).
>
> I suspect the "functional" approach you give above is probably
> uneccessarily sophisticated for my needs... the following works
> perfectly well for me.
>
> typedef void optype(int&, const int&);
>
> void plus_equal(int& a, int b)
> {
> a += b;
> }
>
> struct X
> {
> int a,b;
>
> template<optype OP> void element_wise(X& x)
> {
> OP(a,x.a);
> OP(b,x.b);
> }
>
> X& operator+=(X& x)
> {
> element_wise<plus_equal>(x);
> return *this;
> }
> };



If all you need is int support, you're OK, the solution I posted will
support any type.

>
>
>>In the example you posted,
>>there were numerous issues, I won't go into the details other than to
>>say, you can't pass a function as a template parameter in your case
>>since you don't know what the type of the parameters are

>
>
> Not sure I follow you... I *do* know the parameter types of the function
> I want to pass as template parameter: namely (int&, const int), as
> above. My issue was whether I could pass the global operator+= function
> as a parameter to my to element_wise() ...


OK - then you're all set.

I thought you were looking for a more generic solution. Good luck.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
iterative towers of hanoi using only °elementary° data types bagratte C Programming 16 02-22-2012 05:06 PM
Argument type of function and safe types and types, arguments canhandle safely ittium C++ 4 12-09-2011 11:05 AM
Usual Arithmetic Conversions-arithmetic expressions joshc C Programming 5 03-31-2005 02:23 AM
variadic arithmetic, boolean operators Trent Buck C Programming 3 01-02-2005 02:47 PM
Enhancing valarray with "normal" arithmetic operators =?ISO-8859-1?Q?Christian_Brechb=FChler?= C++ 6 09-14-2003 06:39 PM



Advertisments