Connecting Tech Pros Worldwide Help | Site Map

Help with functor/template/constructor

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 22nd, 2005, 06:48 AM
jack
Guest
 
Posts: n/a
Default Help with functor/template/constructor

Hi there,

I have a function F(x, y, z)
and I want to calculate f(a) + f(b), where f(x) = F(x, x, z0)
z0 is fixed.

Suppose somebody wrote a routine called "Compute" which simply
computes f(a) + f(b) for any one dimensional function f.

Then I create a f1dim which converts any n-dimensional function
G to a one dimensional f(x) = G(x, x, ..., x), via a class
Three_To_One which suppresses (fixes) 1) dimension and 2) function G
in f's argument list.

Also create a class Three_To_Vec which fixes parameter z
in my origional function F, and make it look like a function
with a single array/pointer parameter, i.e., H(w[]) = F(w[0], w[1], z0).

1) If I do not provide a default constructor in Three_To_Vec,
the program won't compile. Why?

2) Why are the destructors of both classes (Three_To_One and Three_To_Vec)
called multiple times, while the constructors are only called once?

Thank you for your help.

Jack

========================== source code in a single file ==================


#include <iostream>
using namespace std;


/* ================= Original function ================== */

double my_3d_f(double x, double y, double z)
{
return x*x*x + 2.0*x*y + 3.0*x*z + x + 3.0*z + 6.0;
}

/* ================= Two Classes used in Functor ============= */

template <class T>
class Three_To_One
{
public:
double (*m_f)(double, int, T);
int m_p1;
T m_p2;

Three_To_One(double(*f)(double, int, T), int p1, T p2)
{
cout << " 3-to-1: c-tor" << endl;
m_f=f;
m_p1=p1;
m_p2=p2;
}

~Three_To_One() { cout << " 3-to-1: D-tor" << endl; }

double operator()(double x)
{
return m_f(x, m_p1, m_p2);
}
};


class Three_To_Vec
{
public:
double (*m_f)(double, double, double);
double m_p;

Three_To_Vec()
{
cout << "3-to-V: default" << endl;
}

Three_To_Vec(double(*f)(double, double, double), double p)
{
cout << "3-to-V: c-tor" << endl;
m_f = f;
m_p = p;
}

~Three_To_Vec() { cout << "3-to-V: D-tor" << endl; }

double operator()(double theta[])
{
return m_f(theta[0], theta[1], m_p);
}
};

/* ========== Somebody's function to compute f(a) + f(b) =================== */

template <class T>
double Compute(T f, double a, double b)
{
return f(a) + f(b);
}

/* ========== Convert n-dimensional to 1-dimensional ================= */

template <class T>
double f1dim(double t, int n, T fnd)
{
int j;
double fval, *x;

x = new double[n];
for(j=0; j < n; ++j)
x[j] = t;
fval = fnd(x);
delete []x;
return fval;
}

/* =========== My function to compute F(a,a,z0) + F(b, b, z0) =================== */

template <class T>
double Go(T fnv, int n, double a, double b)
{
return Compute(Three_To_One<T>(f1dim, n, fnv), a, b);
}


int main()
{

double result;

result = Go(Three_To_Vec(my_3d_f, 3.14159), 3, 2.0, 9.0);
// compute F(2, 2, pi) + F(9, 9, pi)

cout << "result = " << result << endl;

return 0;

}

  #2  
Old July 22nd, 2005, 06:48 AM
Andrey Tarasevich
Guest
 
Posts: n/a
Default Re: Help with functor/template/constructor

jack wrote:[color=blue]
> ...
> 1) If I do not provide a default constructor in Three_To_Vec,
> the program won't compile. Why?[/color]

In your program you instantiate function template 'Go<T>' with deduced
template parameter 'T' equal to 'Three_To_Vec'. This instance of
function template 'Go' in turn will instantiate class template
'Three_To_One<T>' with template parameter 'T' equal to 'Three_To_Vec'.
Now if you look closely you'll see that class template 'Three_To_One<T>'
has a data member named 'm_p2' of type 'T' (which is 'Three_To_Vec' in
our case). This data member is default-constructed, since you don't
mention it in 'Three_To_One<T>'s constructor initializer list. That's
why the compiler needs default constructor for 'Three_To_Vec'.

Maybe you should copy-construct that 'm_p2' (an all other data members)
in 'Three_To_One<T>'s constructor instead of assigning to it:

Three_To_One(double(*f)(double, int, T), int p1, T p2) :
m_f(f), m_p1(p1), m_p2(p2)
{
cout << " 3-to-1: c-tor" << endl;
}

In this case the compiler won't ask for default constructor in
'Three_To_Vec'.
[color=blue]
> 2) Why are the destructors of both classes (Three_To_One and Three_To_Vec)
> called multiple times, while the constructors are only called once?[/color]

You forgot to count copy-constructor calls. Since you didn't declare any
copy-constructors in your classes, the compiler declared (and defined)
them implicitly. These implicitly defined copy-constructors don't output
anything into 'cout', which prevents you from noticing these calls.

--
Best regards,
Andrey Tarasevich

  #3  
Old July 22nd, 2005, 06:48 AM
jack
Guest
 
Posts: n/a
Default Re: Help with functor/template/constructor


"Andrey Tarasevich" <andreytarasevich@hotmail.com> wrote in message
news:103l5jhcdqofdfb@news.supernews.com...

Thank you very much for your detailed explanation!

Jack


  #4  
Old July 22nd, 2005, 07:03 AM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: Help with functor/template/constructor

"jack" <idlor@yahoo.com> wrote...[color=blue]
> I have a function F(x, y, z)
> and I want to calculate f(a) + f(b), where f(x) = F(x, x, z0)
> z0 is fixed.
>
> Suppose somebody wrote a routine called "Compute" which simply
> computes f(a) + f(b) for any one dimensional function f.
>
> Then I create a f1dim which converts any n-dimensional function
> G to a one dimensional f(x) = G(x, x, ..., x), via a class
> Three_To_One which suppresses (fixes) 1) dimension and 2) function G
> in f's argument list.
>
> Also create a class Three_To_Vec which fixes parameter z
> in my origional function F, and make it look like a function
> with a single array/pointer parameter, i.e., H(w[]) = F(w[0], w[1], z0).
>
> 1) If I do not provide a default constructor in Three_To_Vec,
> the program won't compile. Why?[/color]

Could it be because it's needed. Have you run your program? If I do,
I see output that indicates that the default c-tor for Three_To_Vec is
called. I'll leave it to you to find out where.
[color=blue]
> 2) Why are the destructors of both classes (Three_To_One and Three_To_Vec)
> called multiple times, while the constructors are only called once?[/color]

Because there are copy constructors called that you don't register.

Victor


 

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,662 network members.