Archived

This topic is now archived and is closed to further replies.

aboeing

templates & static

Recommended Posts

Hi, I dont even really know how to describe the problem, so here is some code:
#include <stdio.h>
#include <vector>
#define VECTOR std::vector

template <typename T>
class B {
public: 
	void SetA(T &t) {
		A<T>::x.push_back(t); //gcc complains of a parse error here.. ?

		printf("B::SetA, x size:%d\n",A<T>::x.size());
	}
};

class C : public B<int> {
public:
	C() {
		printf("C\n");
		int val=77;
		SetA(val);
	}
};

C global_variable_c; //why wont this set the value?


template <typename T>
class A {
public:
	void PrintX() {
		printf("x size:%d\n",x.size());
	}
static VECTOR<T> x;
};

template <typename T> VECTOR<T> A<T>::x;

int main() {

	C c; //but this will set the value

	//if you comment out the line above, the size reported by PrintX below will be 0


	A<int> a;
	a.PrintX();
}
Program output: C B::SetA, x size:1 C B::SetA, x size:1 x size:1 So, the first C indicates that the global C is indeed constructed, and then increases the size of the static x vector. The second indicates another C is constructed, and increases the size of the static x vector, but again only to one. Calling PrintX, we see the size is only 1. If the c variable in main is commented out, then PrintX will report zero, indicating that the global C has no effect (or not the effect I want it to have anyway) Question 1: The C variable created in main, works correctly (read: does what I want it to do), but the C variable created ''globally'' does not. Why? Question 2: This code compiles fine with MS VC6, DMC 8.35, Intel C 7.1, but doesn''t with mingw gcc 3.2, complaining on line 9 (A < T > ::x.push_back(t); ) Thanks in advance!

Share this post


Link to post
Share on other sites
quote:

Hi, I dont even really know how to describe the problem, so here is some code:

[...]

A<T>::x.push_back(t); //gcc complains of a parse error here.. ?

[...]


A is not defined at this point.

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
A is not defined at this point.

Heh, Oops, sorry, yeah, okay, so if you reorder it so that it goes A,B,C then it will compile with gcc aswell..

But the problem with the global_variable_c still exists.

Share this post


Link to post
Share on other sites
The global_variable_c is declared before the vector, therefore it's constructor will be called before the vector's. This could lead to errors, but in your case it apperantly doesn't. A solution would be to use a static variable in a function:

template <typename T>
class A
{
std::vector<T>& vector()
{
static std::vector<T> instance;
return instance;
}
};

This way the vector will be constructed the first time the function is called.

[edited by - twanvl on November 18, 2003 12:07:47 PM]

[edited by - twanvl on November 18, 2003 12:08:10 PM]

Share this post


Link to post
Share on other sites
Ah, kool thanks! That suggestion works fine.
I have reordered all the code so that all the dependencies are correct, but that didn't solve the problem.

twanvl's Solution:

template <typename T>
class A {
public:
void PrintX() {
printf("x size:%d\n",vector().size());
}
static std::vector<T>& vector()
{
static std::vector<T> instance;
return instance;
}
};
template <typename T>
class B {
public:
void SetA(T &t) {
A<T>::vector().push_back(t);
printf("B::SetA, x size:%d\n",A<T>::vector().size());
}
};


I would still be interested in finding out why the original code didn't work though.

EDIT:
Actually, this solution only works with VC6 & GCC, DMC still gives the incorrect results.
GCC output (correct):
C
B::SetA, x size:1
C
B::SetA, x size:2
x size:2

DMC output (incorrect):
C
B::SetA, x size:1
C
B::SetA, x size:1
x size:1

Any ideas? Thanks.

[edited by - aboeing on November 18, 2003 12:46:19 PM]

Share this post


Link to post
Share on other sites