C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-01-2009, 04:46 PM   #1
Registered User
 
Join Date: Oct 2005
Posts: 271
Linking error with static template class members

The more I think about it, the more I have a feeling I have to change my design but here's the problem, anyway.

I have a templated class. This class has a static class member variable, which is a templated stl_container. Then there is a class derived from this one that tries to call this member variable in a source file, but results in a linker error. Here's some simplified code:

Code:
// in a header file
template <typename T>
class A {
static stl_container<T*>* container;
};

class B : public A<MyClass> {
void do_something();
};

//in a source file
//memory allocation for "container" is in different source file

void B::do_something() {
do_something_to(container);
}
This gives me a linker error saying it can't find "container" being called from "do_something". Which, if I think about it, makes sense because there is no other object file for it to link from.

So I can think of one solution which would be to dump the definition of "do_something" into the class body so it doesn't have to resolve the linking error. But I've got other non-class functions that have to access "container" so that's a no go.

So how do you declare, allocate and use a templated static class variable? Is it possible?

I need this thing to be static because "class A" is a actually a node in a graph structure that links to other nodes in the graph and info on the overall graph (kept in the container) can be updated by any node.
cunnus88 is offline   Reply With Quote
Old 04-01-2009, 09:47 PM   #2
Registered User
 
Join Date: Oct 2005
Posts: 271
After some googling and tinkering, I've found a solution, but I can't say I understand why it works.

Code:
// in a header file
template <typename T>
class A {
static stl_container<T*>* container;
};

//you need a second declaration outside the body of the class
//in the header
template <typename T>
typename A<T>::stl_container<T*>* container;
Why you need the second declaration is beyond me. But it works.
cunnus88 is offline   Reply With Quote
Old 04-01-2009, 10:12 PM   #3
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,759
Why is that so surprising? You have to do that even without templates.

Code:
class A
{
public:
    static int x;
};

int A::x;

int main()
{
    A::x = 0;
    return 0;
}
How could it be otherwise? How does the compiler magically decide which .cpp module the definition of the static member should come from? The "static int x" is only a declaration -- you still need to define the variable in some specific .cpp module.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 04-02-2009, 11:59 AM   #4
Registered User
 
Join Date: Oct 2005
Posts: 271
My previous understanding was that static member variables have to be defined outside the class body, not just declared. Isn't a statement like
Code:
int A::x;
allocating memory as well, and therefore, a definition?

But when you have a template declaration
Code:
template <typename T>
typename A<T>::stl_container<T*>* container;
it's not allocating any memory. It's just repeating a declaration made earlier, n'est ce pas? Seems a little byzantine.
cunnus88 is offline   Reply With Quote
Old 04-02-2009, 12:02 PM   #5
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,759
Why should the template syntax deviate from the non-template syntax?
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 04-02-2009, 12:05 PM   #6
Registered User
 
Join Date: Oct 2005
Posts: 271
True. Consistency is important.
cunnus88 is offline   Reply With Quote
Old 04-02-2009, 12:31 PM   #7
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,781
It's the same as with non-templates.
It may be a declaration or implementation, but one instantiated, when the class is instantiated, it becomes a definition. That is generally a rule of templates - they are a declaration sorts of, but once instantiated, a definition for those particular types is created.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
LNK2001 ERROR!!! need help lifeafterdeath C++ Programming 7 05-27-2008 05:05 PM
template function v.s. template class George2 C++ Programming 3 12-13-2007 01:46 AM
error: template with C linkage michaels-r C++ Programming 3 05-17-2006 08:11 AM
oh me oh my hash maps up the wazoo DarkDays C++ Programming 5 11-30-2001 12:54 PM
bug for static functions in template class Unregistered C++ Programming 3 09-16-2001 06:38 PM


All times are GMT -6. The time now is 04:31 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22