From: PGK on
I've written a simple template metaprogramming loop (below) using a
struct template which requires a loop index, and two function
signatures; one for the base (zero) case, and one for the inductive
(ith) case. As you can see below, I start things off with a call like
this:

Loop2<double (*)(double), void (*)(int), 2 >::foo(f2,f1);

and the output is:

Hello from f1(2).
Hello from f1(1).
Hello from f2(0.123).

My question is, can I reconfigure this code so that I don't have to
explicitly specify the types of the two function pointers? For
example, something "like": Loop2<2>::foo(f2,f1);

Cheers,
P.

inline void f1(int i) { std::cout << "Hello from f1(" << i <<
")." << std::endl; }
inline double f2(double d) { std::cout << "Hello from f2(" << d <<
")." << std::endl; }

template<typename BaseFunc, typename InductiveFunc, int i>
struct Loop2 {
static inline void foo(BaseFunc bFunc, InductiveFunc iFunc) {
iFunc(i);
Loop2<BaseFunc,InductiveFunc,i-1>::foo(bFunc,iFunc);
}
};

template<typename BaseFunc, typename InductiveFunc>
struct Loop2<BaseFunc,InductiveFunc,0> {
static inline void foo(BaseFunc bFunc, InductiveFunc iFunc) {
bFunc(0.123);
}
};

int main(int argc, char *argv[]) {
Loop2<double (*)(double), void (*)(int), 2 >::foo(f2,f1);
return 0;
}

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mateusz Adamczyk on
On 29 Paź, 00:13, PGK <graham.k...(a)gmail.com> wrote:
> ... For example, something "like": Loop2<2>::foo(f2,f1);

You can use fact, that for functions template parameters can
be deducted by compiler. So when You change both function types
from being parameters of struct Loop2, to be parameters
of its member function foo, You get desired syntax (see example).

Regards,
Mateusz
>
> inline void f1(int i) { std::cout << "Hello from f1(" << i <<
> ")." << std::endl; }
> inline double f2(double d) { std::cout << "Hello from f2(" << d <<
> ")." << std::endl; }
>
> template<typename BaseFunc, typename InductiveFunc, int i>
> struct Loop2 {
> static inline void foo(BaseFunc bFunc, InductiveFunc iFunc) {
> iFunc(i);
> Loop2<BaseFunc,InductiveFunc,i-1>::foo(bFunc,iFunc);
> }
>
> };
template<int i>
struct Loop2 {
template<typename BaseFunc, typename InductiveFunc>
static inline void foo(BaseFunc bFunc, InductiveFunc iFunc)
{
iFunc(i);
Loop2<i-1>::foo(bFunc,iFunc);
}

};

> template<typename BaseFunc, typename InductiveFunc>
> struct Loop2<BaseFunc,InductiveFunc,0> {
> static inline void foo(BaseFunc bFunc, InductiveFunc iFunc) {
> bFunc(0.123);
> }
>
> };
template<>
struct Loop2<0> {
template<typename BaseFunc, typename InductiveFunc>
static inline void foo(BaseFunc bFunc, InductiveFunc iFunc)
{
bFunc(0.123);
}

};
>
> int main(int argc, char *argv[]) {
> Loop2<double (*)(double), void (*)(int), 2 >::foo(f2,f1);
> return 0;
>
> }
int main(int argc, char *argv[]) {
Loop2<2 >::foo(f2,f1);
return 0;

}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On 29 oct, 00:13, PGK <graham.k...(a)gmail.com> wrote:
>
> Loop2<double (*)(double), void (*)(int), 2 >::foo(f2,f1);
>
> and the output is:
>
> Hello from f1(2).
> Hello from f1(1).
> Hello from f2(0.123).
>
> My question is, can I reconfigure this code so that I don't have to
> explicitly specify the types of the two function pointers? For
> example, something "like": Loop2<2>::foo(f2,f1);

Sure, just use a template function that will be able to infer the
template parameters.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Vidar Hasfjord on
On Oct 28, 11:13 pm, PGK <graham.k...(a)gmail.com> wrote:
> I've written a simple template metaprogramming loop [...]
>
> [Loop2 <double (*)(double), void (*)(int), 2>::foo (f2,f1);]
>
> My question is, can I reconfigure this code so that I don't have to
> explicitly specify the types of the two function pointers? For
> example, something "like": Loop2<2>::foo(f2,f1);

Sure, you can exploit function template argument deduction:

template <int i, typename BaseFunc, typename InductiveFunc>
void static_loop (BaseFunc fb, InductiveFunc fi) {
Loop2 <BaseFunc, InductiveFunc, i>::foo (fb, fi);
}

int main (int, char*[]) {
static_loop <2> (f2, f1);
return 0;
}

Regards,
Vidar Hasfjord


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 29 Okt., 00:13, PGK <graham.k...(a)gmail.com> wrote:
> I've written a simple template metaprogramming loop (below) using a
> struct template which requires a loop index, and two function
> signatures; one for the base (zero) case, and one for the inductive
> (ith) case. As you can see below, I start things off with a call like
> this:
>
> Loop2<double (*)(double), void (*)(int), 2 >::foo(f2,f1);
>
> and the output is:
>
> Hello from f1(2).
> Hello from f1(1).
> Hello from f2(0.123).
>
> My question is, can I reconfigure this code so that I don't have to
> explicitly specify the types of the two function pointers? For
> example, something "like": Loop2<2>::foo(f2,f1);
>
> Cheers,
> P.
>
> inline void f1(int i) { std::cout << "Hello from f1(" << i <<
> ")." << std::endl; }
> inline double f2(double d) { std::cout << "Hello from f2(" << d <<
> ")." << std::endl; }

A function that returns a non-void result which normally exits
without return causes undefined behaviour.

> template<typename BaseFunc, typename InductiveFunc, int i>
> struct Loop2 {
> static inline void foo(BaseFunc bFunc, InductiveFunc iFunc) {
> iFunc(i);
> Loop2<BaseFunc,InductiveFunc,i-1>::foo(bFunc,iFunc);
> }
> };
>
> template<typename BaseFunc, typename InductiveFunc>
> struct Loop2<BaseFunc,InductiveFunc,0> {
> static inline void foo(BaseFunc bFunc, InductiveFunc iFunc) {
> bFunc(0.123);
> }
> };
>
> int main(int argc, char *argv[]) {
> Loop2<double (*)(double), void (*)(int), 2 >::foo(f2,f1);
> return 0;
> }

My first idea would be to split the iteration template parameter
from the actual functor types:

template<int i>
struct Loop2 {
template<typename BaseFunc, typename InductiveFunc>
static void foo(BaseFunc bFunc, InductiveFunc iFunc) {
iFunc(i);
Loop2<i-1>::foo(bFunc,iFunc);
}
};

template<>
struct Loop2<0> {
template<typename BaseFunc, typename InductiveFunc>
static void foo(BaseFunc bFunc, InductiveFunc iFunc) {
bFunc(0.123);
}
};

int main() {
Loop2<2>::foo(f2,f1);
}

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 |  Next  |  Last
Pages: 1 2
Prev: Is this correct C++?
Next: Simplester MetaLoop