Jump to content
  • Advertisement
Sign in to follow this  
Basiror

template class member function msvc++

This topic is 4885 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi i had a little problem with msvc++ last night in the header file template<class T> someclass { public: void somefunction(); } and inthe source file .cpp template<class T> someclass<T>::somefunction() { } the code looks correct to me and the object file compiles fine but when i use the class in another module it brings a linking error unresolved external symbol it doesn t find the member function with gcc it seems to work is it a bug in their compiler or am i doing something wrong here? when i move the implementation completely into the header file everything works fine

Share this post


Link to post
Share on other sites
Advertisement
The file using this class only gets the header, not the source file. Why would you even expect it to know that the function is a template?

Share this post


Link to post
Share on other sites
All code for a templated class must be in a header file, including non-inlined functions. This may seem strange, but it's quite logical if you think about it. A templated function isn't defining a function itself, it's defining a template for a function, from which an actual function can be generated. There will be a seperate version of the templated function in question created for each different set of template parameters that you supply in different areas of the program. Each time it encounters a new set of parameters, it needs to create a new implemented version of the template in that module. The only way this can be done is if the compiler has the template for that function when it is compiling that module.

Share this post


Link to post
Share on other sites
I use msvc and template, and put the implementation in a .cpp file. What I did was at the end of the cpp file, define something like this:
template class CSomeTemplate<short>;
template class CSomeTemplate<int>;
... etc, for all types of templates you want (eg. short and int).

Share this post


Link to post
Share on other sites
Quote:
Original post by xinvar
I use msvc and template, and put the implementation in a .cpp file. What I did was at the end of the cpp file, define something like this:
template class CSomeTemplate<short>;
template class CSomeTemplate<int>;
... etc, for all types of templates you want (eg. short and int).

Although it works, it's more upkeep. It's better just stick it in the .h file and forget about it. Usually, once I write a templated class, I forget about it's implementation and just use it over and over again. Now, I'll usually have a large number of template classes in my application. It'd be a real pain to have to go back through all of those source files every time I add a new class that needs templates.

Share this post


Link to post
Share on other sites
which STL are you using?
Dinkumware?
SGI
or
SGIPort?

currently i am working with msvc++6.0 and the stl shipped with the compiler
but i encountered another problem



namespace cross
{
template<typename T> class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;

template<class U>
struct rebind { typedef pool_allocator<U> other; };

//return a object of n bytes
char *_Charalloc(size_type n)
{
};

//constructor
pool_allocator()
{
assert((m_pPool = new pool_list<T,1024>()) != NULL);
};

//copy constructor
/*pool_allocator(const pool_allocator& alloc)
{
assert((m_pPool = alloc.m_pPool) != NULL);
};*/

template<class U>pool_allocator(const pool_allocator<U> & arg)
{
};
//deconstructor
~pool_allocator()
{
delete m_pPool;
};

//returns a pointer to x
pointer address(reference x) const
{
return &x;
};

//returns a const_pointer to x
const_pointer address(const_reference x)
{
return &x;
};

//allocates a array of n elements
pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0)
{
if(n==1)
return m_pPool->allocate();
return NULL;
};

//deallocate a array of n elements
void deallocate(pointer p, size_type n)
{
if(n==1)
m_pPool->deallocate(p);
};
size_type max_size() {return 0;};

//placement new: call the constructor of the object p
void construct(pointer p, const T& val)
{
new(p) T(val);
}
//call the destructor of the object p
void destroy(pointer p)
{
p->T::~T();
}
private:
pool_list<T,1024> *m_pPool;
};
}




Iget the following error message meaning that he can convert _Node* to char*(I used the allocator with std:list<char,alloc>
typedef cross:pool_allocator<char> alloc; without the typedef it doesn t seem to compile it

i think i ll install the gcc for windows tomorrow, the ms compiler drives me crazy
Quote:

c:\programme\microsoft visual studio\vc98\include\list(392) : error C2664: 'deallocate' : Konvertierung des Parameters 1 von 'struct std::list<char,class cross::pool_allocator<char> >::_Node *' in 'char *' nicht moeglich
Die Typen, auf die verwiesen wird, sind nicht verwandt; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
c:\programme\microsoft visual studio\vc98\include\list(392) : Bei der Kompilierung der Member-Funktion 'void __thiscall std::list<char,class cross::pool_allocator<char> >::_Freenode(struct std::list<char,class cross::pool_allocator<char> >::
_Node *)' der Klassenvorlage

Share this post


Link to post
Share on other sites
Quote:
Original post by Basiror
currently i am working with msvc++6.0 and the stl shipped with the compiler


Well that says it all, VC++ 6.0 is a poorly standard compliant C++ compiler (especially for templates) and a poorly implemented standard library. VC++ 6.0 doesn't support template members correctly i.e. rebind trick doesn't work on VC++ 6.0, VC++ 6.0 does an ugly hack to get round that limitation for its imp of the standard library.

Anyways i suggest either you use different modern C++ compiler otherwise if you want an MS compiler get VC++ 7.1 or 8.0 both of which is freely downloadable (VC++ 7.1 toolkit comes with no IDE, you can hook it up VC++ 6.0 IDE however).

On a side note, its not a good idea for max_size to return return 0, if you don't have a particular maximum size to return then return size_type(-1) / sizeof(T);.

Also p->T::~T(); is redundant, just do p->~T() and make sure your including header new to get placement new operator. Next, you better define equality and inequality operators for you allocator type (be it member or free function it makes no difference). Lastly you still need to define a copy constructor (unless the default behaviour of a member-wise copy is fine) because a templated constructor isn't a copy constructor, you need them both however for STL compliant allocator type as far as i'm aware.

[Edited by - snk_kid on July 29, 2005 6:46:17 PM]

Share this post


Link to post
Share on other sites
the max_size isn t correct yes because i havent finished the allocator yet
i just let it return 0 to make it compile

as for the copy constructor, the vc6.0 compiler brings an error message that it s already declared maybe another bug ^^

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!