Integer printer won't compile

P

Protoman

Can you help me figure out why this integer printing program won't
compile? I've looked far and wide in my diagnostics to figure out why,
but I'm lost. Here's the code:

#include <iostream>
#include <cstdlib>
using namespace std;

template<int I>
class _name
{
public:
static void f()
{
static int i=0;
cout << i << endl;
i++;
_name<go?(I-1):0>::f();
}
private:
enum {go=(I-1)!=0};
};

// Specialization provides base case for
// recursion
template<>
class _name<0>
{
public:
static void f(int i){return;}
};

int main()
{
// Equivalent loop code
_name<5>::f();
system("PAUSE");
return 0;
}

Any help, please? Thanks!!!!!
 
P

Protoman

OK, I fixed the compiling prob, but now, instead of printing 0-5, it
prints all 0s. And it's static !!!!!
 
A

Andre Kostur

OK, I fixed the compiling prob, but now, instead of printing 0-5, it
prints all 0s. And it's static !!!!!

a) Include the text that you are referring to... makes it hard to quote
properly.
#include <iostream>
#include <cstdlib>
using namespace std;

template<int I>
class _name
{
public:
static void f()
{
static int i=0;
cout << i << endl;
i++;
_name<go?(I-1):0>::f();
}
private:
enum {go=(I-1)!=0};
};

// Specialization provides base case for
// recursion
template<>
class _name<0>
{
public:
static void f(int i){return;}
};

int main()
{
// Equivalent loop code
_name<5>::f();
system("PAUSE");
return 0;
}

b) Because it's static, you have 5 instances of the local variable i,
let's name them as follows:

_name<5>::f::i
_name<4>::f::i
_name<3>::f::i
_name<2>::f::i
_name<1>::f::i

Each one is initialized to zero, and is incremented to 1, but you never
see it.

c) Why aren't you just using a template function instead of an entire
class?

d) Post compilable, running code. Yours doesn't. There is no function
named f in the _name<0> instance.

e) What is "go" contributing to this problem? It does not appear to do
anything useful.

f) And if you fix all of these, you'll get 0-4.
 
A

Andre Kostur

d) Post compilable, running code. Yours doesn't. There is no function
named f in the _name<0> instance.

Err... I meant "no function named f *taking no parameters* in the _name
<0> instance".
 
P

Protoman

OK, I fixed that, but how do I initialize my static var? I have no clue
on how to do it for a template.

Code:

template<int I>
class _name
{
public:
static void f()
{
cout << i << endl;
_name<go?(I-1):0>::f();
i++;
}
private:
enum {go=(I-1)!=0};
static int i;
};

// Specialization provides base case for
// recursion
template<>
class _name<0>
{
public:
static void f(){return;}
};
template<I> int _name<int I>::i=0;

int main()
{
// Equivalent loop code
_name<5>::f();
system("PAUSE");
return 0;
}

Help, please. Thanks!!!!!
 
A

Andre Kostur

OK, I fixed that, but how do I initialize my static var? I have no clue
on how to do it for a template.

Code:

template<int I>
class _name
{
public:
static void f()
{
cout << i << endl;
_name<go?(I-1):0>::f();
i++;
}
private:
enum {go=(I-1)!=0};
static int i;
};

// Specialization provides base case for
// recursion
template<>
class _name<0>
{
public:
static void f(){return;}
};
template<I> int _name<int I>::i=0;

int main()
{
// Equivalent loop code
_name<5>::f();
system("PAUSE");
return 0;
}

Help, please. Thanks!!!!!

You're back in the same place you just left. You still have 5 independant
instances of i. Presumably you're trying to only have one instance of i
shared among the 5 completely unrelated classes. There's a couple of ways
of doing it.

1) a simple global variable (ie: int i = 0;).
2) a common base class with a static protected variable, and the template
inherits from that base class.

I guess a more basic question... what are you actually trying to
accomplish?
 
P

Protoman

OK, I inited the static var, but I still get 0s. Why the hell won't it
increment?!!!!!!!!!!!!!!?

Code:

//supplies static var i to _name template
struct var
{
protected:
static int i;
};

template<int I>
class _name:protected var
{
public:
static void f()
{
static int j=i;
cout << j << endl;
j++;
_name<go?(I-1):0>::f();
}
private:
enum {go=(I-1)!=0};
};
int var::i=0;
// Specialization provides base case for
// recursion
template<>
class _name<0>
{
public:
static void f(){return;}
};


int main()
{
// Equivalent loop code
_name<5>::f();
system("PAUSE");
return 0;
}

Help, please!!!!!!! Thanks!!!!!!!!!!!!!!!!!!!!
 
P

Protoman

Andre said:
You're back in the same place you just left. You still have 5 independant
instances of i. Presumably you're trying to only have one instance of i
shared among the 5 completely unrelated classes. There's a couple of ways
of doing it.

1) a simple global variable (ie: int i = 0;).
2) a common base class with a static protected variable, and the template
inherits from that base class.

I guess a more basic question... what are you actually trying to
accomplish?

Print 0-5!!!!! And did you read my last post?!? I made _name
protectedly inherit from the struct var, which contains the static var
i. And its still not working!!!!! And globals are evil!!!!
 
A

Andre Kostur

Print 0-5!!!!!

That's easy:

#include <iostream>
int main() { cout << "0\n1\n2\n3\n4\n5\n"; }.

But I suspect you have more requirements than simply printing 0-5 ...
And did you read my last post?!? I made _name
protectedly inherit from the struct var, which contains the static var
i. And its still not working!!!!! And globals are evil!!!!

Your last post had not made it to my newsserver yet. Do not assume the
method by which I read USENET. Which I why I quoted the post that I'm
replying to. (And, yes, one should avoid global variables... I'm only
pointing it out as an option).

Quoting the other post of yours:
//supplies static var i to _name template
struct var
{
protected:
static int i;
};

template<int I>
class _name:protected var
{
public:
static void f()
{
static int j=i;
cout << j << endl;
j++;
_name<go?(I-1):0>::f();
}
private:
enum {go=(I-1)!=0};
};
int var::i=0;
// Specialization provides base case for
// recursion
template<>
class _name<0>
{
public:
static void f(){return;}
};


int main()
{
// Equivalent loop code
_name<5>::f();
system("PAUSE");
return 0;
}

You did not just make i inhereted from a common base class, you've also
added a j variable for some reason. Also, why do you need a variable at
all? Why not:

#include <iostream>
using namespace std;
template <int I> class _name {
public:
static void f() { _name<I - 1>::f(); cout << I << "\n"; };
};

template <> class _name<0> {
public:
static void f() { cout << "0\n"; };
};

int main() { _name<5>::f(); }

Heck.. why bother with a templated solution at all? Why not:

#include <iostream>
using namespace std;
void f(int i) {
if (i == 0) { cout << "0\n"; return; }
f(i - 1); cout << i << "\n";
}

int main() { f(5); }
 
P

Protoman

Andre said:
That's easy:

#include <iostream>
int main() { cout << "0\n1\n2\n3\n4\n5\n"; }.

But I suspect you have more requirements than simply printing 0-5 ...


Your last post had not made it to my newsserver yet. Do not assume the
method by which I read USENET. Which I why I quoted the post that I'm
replying to. (And, yes, one should avoid global variables... I'm only
pointing it out as an option).

Quoting the other post of yours:


You did not just make i inhereted from a common base class, you've also
added a j variable for some reason. Also, why do you need a variable at
all? Why not:

#include <iostream>
using namespace std;
template <int I> class _name {
public:
static void f() { _name<I - 1>::f(); cout << I << "\n"; };
};

template <> class _name<0> {
public:
static void f() { cout << "0\n"; };
};

int main() { _name<5>::f(); }

Heck.. why bother with a templated solution at all? Why not:

#include <iostream>
using namespace std;
void f(int i) {
if (i == 0) { cout << "0\n"; return; }
f(i - 1); cout << i << "\n";
}

int main() { f(5); }

Because I want to make use of TMP!!!! And, no, I don't have anyother
requirements other than printing 0-5. Thanks!!!!
 
B

Ben Pope

Protoman said:
no, I don't have anyother
requirements other than printing 0-5. Thanks!!!!

Well then you're making it much harder than need be. The solution is
above, although I'm unsure if you want that or:

#include <iostream>
int main() { std::cout << "0-5"; }

Ben Pope
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top