View Single Post
  #2 (permalink)  
Old 10-29-2011, 05:36 PM
Daniel Krügler
Guest
 
Posts: n/a
Default 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! ]
Reply With Quote