Can I use typedef to define types used in the return type in template function? 
November 7th, 2005, 12:15 AM
| | | 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);
} | 
November 7th, 2005, 01:15 PM
| | | 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);
} | 
November 7th, 2005, 02:15 PM
| | | 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 | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | 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.
|