Connecting Tech Pros Worldwide Help | Site Map

Can I use typedef to define types used in the return type in template function?

 
LinkBack Thread Tools Search this Thread
  #1  
Old November 7th, 2005, 12:15 AM
PengYu.UT@gmail.com
Guest
 
Posts: n/a
Default Can I use typedef to define types used in the return type in template function?

I have the following sample program, which can convert function object
with 1 argument into function object with 2 arguments. It can also do +
between function object of the same type.

The last line is very long. I'm wondering if there is any way to
suppress it. I can only think of typedef. But I'm not sure whether I
can use typedef for the return type.

Would you please help me? Please don't be daunted by the length of the
code.

Thanks,
Peng

/*main.cc*/
#include "expression_templates.h"
#include <cassert>
#include <complex>

int main(void) {
sample_1_arg_fun<std::complex<double> > f;
std::cout << cast1stArg(f)(0, 1) << std::endl;
std::cout << cast2ndArg(f)(0, 1) << std::endl;
std::cout << (cast2ndArg(f) + cast2ndArg(f))(2, 1) << std::endl;
}

/*expression_templates.h*/
#include <iostream>
#include <functional>
#include <algorithm>
#include <limits>

template <typename T>
class sample_1_arg_fun {
public:
typedef T return_type;
return_type operator()(int i) const { return (i>= the_min_limit()
&& i <= the_max_limit())?i:0; }
int the_min_limit() const { return std::numeric_limits<int>::min();
}
int the_max_limit() const { return std::numeric_limits<int>::max();
}
};

struct LimitsUnion {
int min_limit(int min_limit1, int min_limit2) const { return
std::min(min_limit1, min_limit2); }
int max_limit(int max_limit1, int max_limit2) const { return
std::max(max_limit1, max_limit2); }
};

struct LimitsIntersection {
int min_limit(int min_limit1, int min_limit2) const { return
std::max(min_limit1, min_limit2); }
int max_limit(int max_limit1, int max_limit2) const { return
std::min(max_limit1, max_limit2); }
};

template <typename BinOp>
struct BinOpTraits;

template <typename T>
struct BinOpTraits<std::plus<T> >{
typedef LimitsUnion limit_op;
};

template <typename T1, typename ExprT1, typename T2, typename ExprT2,
typename BinOp>
class Expr2Args;

template <typename T, typename ExprT>
class Expr2Args<T, ExprT, void, void, void> {
public:
typedef T return_type;
Expr2Args(const ExprT e) : _e(e) {}
return_type operator()(int i1, int) const { return _e(i1); }
int the_1st_min_limit() const { return e.the_min_limit(); }
int the_1st_max_limit() const { return e.the_max_limit(); }
int the_2nd_min_limit() const { return
std::numeric_limits<int>::min(); }
int the_2nd_max_limit() const { return
std::numeric_limits<int>::max(); }
private:
const ExprT _e;
};

template <typename T, typename ExprT>
class Expr2Args<void, void, T, ExprT, void> {
public:
typedef T return_type;
Expr2Args(const ExprT e) : _e(e) {}
return_type operator()(int, int i2) const { return _e(i2); }
int the_1st_min_limit() const { return
std::numeric_limits<int>::min(); }
int the_1st_max_limit() const { return
std::numeric_limits<int>::max(); }
int the_2nd_min_limit() const { return e.the_min_limit(); }
int the_2nd_max_limit() const { return e.the_max_limit(); }
private:
const ExprT _e;
};

template <typename T, typename ExprT1, typename ExprT2, typename BinOp>
class Expr2Args<T, ExprT1, T, ExprT2, BinOp> {
typedef typename BinOpTraits<BinOp>::limit_op limit_op;
public:
typedef T return_type;
Expr2Args(const ExprT1 e1, const ExprT2 e2) : _e1(e1), _e2(e2) {}
return_type operator()(int i1, int i2) const { return
BinOp()(_e1(i1, i2), _e2(i1, i2)); }
int the_1st_min_limit() const { return
limit_op::min_limit(_e1.the_1st_min_limit(), _e2.the_1st_min_limit());
}
int the_1st_max_limit() const { return
limit_op::max_limit(_e1.the_1st_max_limit(), _e2.the_1st_max_limit());
}
int the_2nd_min_limit() const { return
limit_op::min_limit(_e1.the_2nd_min_limit(), _e2.the_2nd_min_limit());
}
int the_2nd_max_limit() const { return
limit_op::max_limit(_e1.the_2nd_max_limit(), _e2.the_2nd_max_limit());
}
private:
const ExprT1 _e1;
const ExprT2 _e2;
};

template <typename ExprT>
Expr2Args<typename ExprT::return_type, ExprT, void, void, void>
cast1stArg(const ExprT e) {
return Expr2Args<typename ExprT::return_type, ExprT, void, void,
void>(e);
}

template <typename ExprT>
Expr2Args<void, void, typename ExprT::return_type, ExprT, void>
cast2ndArg(const ExprT e) {
return Expr2Args<void, void, typename ExprT::return_type, ExprT,
void>(e);
}

template <typename T11, typename ExprT11, typename T12, typename
ExprT12, typename BinOp1, typename T21, typename ExprT21, typename T22,
typename ExprT22, typename BinOp2>
Expr2Args<typename Expr2Args<T11, ExprT11, T12, ExprT12,
BinOp1>::return_type, Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>,
typename Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>::return_type,
Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>, std::plus<typename
Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>::return_type> >
operator+(const Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>& e1,
const Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>& e2) {
return Expr2Args<typename Expr2Args<T11, ExprT11, T12, ExprT12,
BinOp1>::return_type, Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>,
typename Expr2Args<T21, ExprT21, T22, ExprT22, BinOp1>::return_type,
Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>, std::plus<typename
Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>::return_type> >(e1, e2);
}


  #2  
Old November 7th, 2005, 01:15 PM
Aleksey Loginov
Guest
 
Posts: n/a
Default Re: Can I use typedef to define types used in the return type in template function?


PengYu.UT@gmail.com wrote:[color=blue]
> I have the following sample program, which can convert function object
> with 1 argument into function object with 2 arguments. It can also do +
> between function object of the same type.
>[/color]

what is your main goal?
[color=blue]
> The last line is very long. I'm wondering if there is any way to
> suppress it. I can only think of typedef. But I'm not sure whether I
> can use typedef for the return type.
>
> Would you please help me? Please don't be daunted by the length of the
> code.
>
> Thanks,
> Peng
>
> /*main.cc*/
> #include "expression_templates.h"
> #include <cassert>
> #include <complex>
>
> int main(void) {
> sample_1_arg_fun<std::complex<double> > f;
> std::cout << cast1stArg(f)(0, 1) << std::endl;
> std::cout << cast2ndArg(f)(0, 1) << std::endl;
> std::cout << (cast2ndArg(f) + cast2ndArg(f))(2, 1) << std::endl;
> }
>
> /*expression_templates.h*/
> #include <iostream>
> #include <functional>
> #include <algorithm>
> #include <limits>
>
> template <typename T>
> class sample_1_arg_fun {
> public:
> typedef T return_type;
> return_type operator()(int i) const { return (i>= the_min_limit()
> && i <= the_max_limit())?i:0; }
> int the_min_limit() const { return std::numeric_limits<int>::min();
> }
> int the_max_limit() const { return std::numeric_limits<int>::max();
> }
> };
>
> struct LimitsUnion {
> int min_limit(int min_limit1, int min_limit2) const { return
> std::min(min_limit1, min_limit2); }
> int max_limit(int max_limit1, int max_limit2) const { return
> std::max(max_limit1, max_limit2); }
> };
>[/color]

any reasons not to use "static max_limit(int, int)"?
[color=blue]
>
> template <typename T11, typename ExprT11, typename T12, typename
> ExprT12, typename BinOp1, typename T21, typename ExprT21, typename T22,
> typename ExprT22, typename BinOp2>
> Expr2Args<typename Expr2Args<T11, ExprT11, T12, ExprT12,
> BinOp1>::return_type, Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>,
> typename Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>::return_type,
> Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>, std::plus<typename
> Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>::return_type> >
> operator+(const Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>& e1,
> const Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>& e2) {
> return Expr2Args<typename Expr2Args<T11, ExprT11, T12, ExprT12,
> BinOp1>::return_type, Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>,
> typename Expr2Args<T21, ExprT21, T22, ExprT22, BinOp1>::return_type,
> Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>, std::plus<typename
> Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>::return_type> >(e1, e2);
> }[/color]

may be this:

template <typename T1, typename T2>
Expr2Args< typename T1::return_type, T1, typename T2::return_type,
T2, std::plus<typename T1::return_type> >
operator+(const T1& e1, const T2& e2) {
return Expr2Args< typename T1::return_type, T1, typename
T2::return_type,T2, std::plus<typename T1::return_type> >(e1, e2);
}

  #3  
Old November 7th, 2005, 02:15 PM
Aleksey Loginov
Guest
 
Posts: n/a
Default Re: Can I use typedef to define types used in the return type in template function?


Aleksey Loginov wrote:[color=blue]
>
> may be this:
>
> template <typename T1, typename T2>
> Expr2Args< typename T1::return_type, T1, typename T2::return_type,
> T2, std::plus<typename T1::return_type> >
> operator+(const T1& e1, const T2& e2) {
> return Expr2Args< typename T1::return_type, T1, typename
> T2::return_type,T2, std::plus<typename T1::return_type> >(e1, e2);
> }[/color]

my mistake.

template< typename T11, typename ExprT11, typename T12, typename
ExprT12, typename BinOp1, typename T21, typename ExprT21, typename T22,

typename ExprT22, typename BinOp2, typename T1=Expr2Args<T11, ExprT11,
T12, ExprT12, BinOp1>, typename T2=Expr2Args<T21, ExprT21, T22,
ExprT22, BinOp2> >
Expr2Args< typename T1::return_type, T1, typename T2::return_type,
T2, std::plus<typename T1::return_type> >
operator+(const Expr2Args<T11, ExprT11, T12, ExprT12, BinOp1>& e1,
const Expr2Args<T21, ExprT21, T22, ExprT22, BinOp2>& e2) { ... }

and this
http://osl.iu.edu/~tveldhui/papers/t...ues01.html#l14

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,989 network members.