Re: Template-based code doesn't compile
Am 29.10.2011 10:20, schrieb late-enthusiast:
Hi
I can't compile the following code (with gcc 3.4.4):
There is a lot going wrong in this code. Let's start dissecting it:
I have this code in the "totals.h" file:
// beginning of totals.h
#include<list>
using namespace std;
Please don't do this in a header. Any user-code, that includes this
header might get name collisions, because of this.
#ifndef __TOTAL_H_
#define __TOTAL_H_
I wonder, why you have this header protection *following* the above
shown code.
// Parent
template<typename T> class Total
{
public:
Total<T>(const list<T>& l);
~Total();
Why are you declaring a user-defined destructor? There is no need for
it, just don't do it.
virtual T compute();
private:
list<T> figures;
};
So, template Total does not have a default constructor, right? What is
actually the reason for the member figures here? You never seem to use
it in your program.
// Sum template
template<typename T> class Sum : public Total<T>
{
public:
Sum<T>(const list<T>& l) : figures(l) {}
This constructor implicitly calls the default constructor of the base
class Total<T>. I assume, the intention is to call the constructor
Total<T>(const list<T>&) here. I also note, that member total is never
initialized, so your code runs amok in compute, if this is a built-in type.
~Sum() {}
Same argument as with the destructor of Total, just remove that.
T compute();
private:
list<T> figures;
T total;
};
template<typename T>
T Sum<T>::compute()
{
typename list<T, allocator<T> >::iterator i = figures.begin();
while (i != figures.end())
{
total += *i;
i++;
}
return total;
}
The reference to list<T, allocator<T> > is not wrong, but misleading,
why not using list<T> as in your member declaration?
This function shows that it is essential that member total is somehow
initialized, either in the constructor or at the beginning of compute().
// Average template
template<typename T> class Average : public Total<T>
{
public:
Average<T>(const list<T>& l) : figures(l) {}
Same problem here as in Sum: You need to call the constructor
Total<T>(const list<T>&). This code implicitly calls the default
constructor of Total<T>, but there is none.
~Average() {}
Same problem as before, just remove that.
T compute();
private:
list<T> figures;
T total;
Same problem as in Sum: You need to initialize member total in the
constructor or in your compute function.
};
template<typename T>
T Average<T>::compute()
{
typename list<T, allocator<T> >::iterator i = figures.begin();
while (i != figures.end())
{
total += *i;
i++;
}
return (total/figures.size());
}
Same problems as in Sum<T>::compute.
Then I have this in "sum.cpp"
// beginning of sum.cpp
#include<stdio.h>
#include<list>
#include "totals.h"
using namespace std;
int main(int argc, char *argv[])
{
int N = atoi(argv[1]);
You miss to add a header to atoi, presumably this should be <stdlib.h>
list<double> figures;
int x = 0;
while (x != N)
{
figures.push_front((double) (x * (x + 2) + 1));
x++;
}
Sum<double> *sum = new Sum(figures);
You need to write new Sum<double>(figures) here, because you are
instantiating new Sum<double>
Average<double> *avg = new Average(figures);
Same problem here, write new Average<double>(figures) instead.
printf(" sum = %8.2f, average = \n", sum->compute(), avg-
compute());
You miss a format specifier for the argument avg->compute().
It's probably because I haven't placed the "typename" keyword
somewhere, but I can't spot the place.
No, but several things else ;-)
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! ]