473,387 Members | 1,575 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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;

}
Jul 22 '05 #1
3 2050
jack wrote:
...
1) If I do not provide a default constructor in Three_To_Vec,
the program won't compile. Why?
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'.
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?


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

Jul 22 '05 #2

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:10*************@news.supernews.com...

Thank you very much for your detailed explanation!

Jack
Jul 22 '05 #3
"jack" <id***@yahoo.com> wrote...
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?
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.
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?


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

Victor
Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: CoolPint | last post by:
Can anyone explain how I can make the following function accept an default arguement for the last parameter, which should be an optional functor? template <typename T, typename FUNCTOR> void...
3
by: CoolPint | last post by:
I have implemented a generic priority queue below and tested it works fine, but I have one small problem I cannot understand. I have type parameter F which determines the priority so that users can...
8
by: Amit | last post by:
Hello all. If I want to use an object both as a Functor and also, if I pass a function pointer, how can it be done ? For instance, I have something like this template< typename Iter, typename...
8
by: daniel.w.gelder | last post by:
Hello, I have been trying to write a functor template for a week now and I'm just having tons of trouble because I don't understand an issue that I guess is pretty basic to this task. ...
4
by: daniel.w.gelder | last post by:
I wrote a template class that takes a function prototype and lets you store and call a C-level function, like this: inline string SampleFunction(int, bool) {..} functor<string (int, bool)>...
12
by: aaragon | last post by:
Hi everyone, I'm trying to provide some external functionality to a class through a functor object defined by the user. The concept is as follows: template <class Functor> class ClassA {...
5
by: Fei Liu | last post by:
Hello, I have a situation where I need to design a library for multi-thread application, each thread does some work in a client supplied std::ptr_fun(free_function) or a functor. Now since it's...
2
by: aaragon | last post by:
Hi guys, Is there a way to return a functor from a recursive call that takes different paths? Let's say that I have a tree structure like: root | first child ---- nextSibling ----nextSibling...
11
by: Dijkstra | last post by:
Hi folks! First, this is the code I'm using to expose the problem: ------------------------------------------------------------------ #include <functional> #include <string> #include...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.