Sign in to follow this  
Dave Eberly

Linker errors for class templated-member functions

Recommended Posts

Dave Eberly    1173
I am using Visual Studio 2008. In one of my libraries I build, I have a class of the form shown next. The contents of this source block are in a header file.
class MyClass
{
public:
    template <typename T>
    void MyFunction1 (int, const AnotherClass<T>*);

    template <typename T>
    void MyFunction2 (int, const AnotherClass<T>*);
};

template <typename T>
void MyClass:MyFunction1 (int i, const AnotherClass<T>* p) { implementation }

template <typename T>
void MyClass:MyFunction2 (int i, const AnotherClass<T>* p) { implementation }

The library uses MyClass/MyFunction1/MyFunction2 for a variety of template parameters. The library compiles, links, and I get a *.lib file for my applications to use. When I try to build my application, I get linker errors about "unresolved external symbol" for *some* of the MyFunction2 instantiations but not *all* of the MyFunction2 instantiations. The linker specifies that these are referenced in the library (and the information is consistent with how I structured the library). Strangely enough, there are no complaints from the linker about MyFunction1. I also have occurrences in the library for this templated member function. It has the appearance that not all of the template references in my library are causing the compiler to generate code for them. I tried to write a small test program that reproduces the problem, but I was unsuccessful (the linking worked as I expected). So I am looking for any ideas that might help me figure out what the problem is. Thanks.

Share this post


Link to post
Share on other sites
dmail    116
Is it possible for you to post the actual errors?
The problem as I am sure you are aware with none working test code is that it is useless, it contains two typos as well.
Quote:
MyClass:MyFunction1

Also does that test code demonstrate the real code well, ie are the templated functions not inlined.

[Edited by - dmail on November 11, 2009 1:27:29 PM]

Share this post


Link to post
Share on other sites
Dave Eberly    1173
Quote:
Original post by dmail
Is it possible for you to post the actual errors?


Of course, but I think the "unresolved external symbol" statement I made is sufficient. It is not possible to post the libraries and application code as it is on the order of 100K lines of code.

Quote:

The problem as I am sure you are aware with none working test code is that it is useless, it contains two typos as well.


My intent of posting the "pseudocode" was to show that (1) I have templated member functions in a class and (2) the bodies are defined outside the class. I did not intend for someone just to cut-and-paste that code and compile it. As I mentioned in my post, I tried to write a small test program to reproduce the error, but I could not reproduce it. Had I done so, I would have posted the actual compilable/linkable code. That is why I posted I am looking for ideas.

Quote:

Also does that test code demonstrate the real code well, ie are the templated functions not inlined.


There is no "inline" modifier. The standard template code generation mechanism should work just fine.

Exploring further, I had the compiler generate mixed ASM/source output. The MyFunction1 template code was generated and shows up in the ASM/source listing. The MyFunction2 template code was not generated; the function is tagged as "EXTRN" by the compiler. In both cases the templates involve a class A calling the function for a class B. Why the two templates are being treated differently is the mystery.

Share this post


Link to post
Share on other sites
dmail    116
Quote:

Of course, but I think the "unresolved external symbol" statement I made is sufficient. It is not possible to post the libraries and application code as it is on the order of 100K lines of code.


My reason for asking to see the error is so we could confirm the name of the function and the name in the error.

Share this post


Link to post
Share on other sites
Dave Eberly    1173
Quote:
Original post by SiCrane
Did you try explicit template instantiation?


dmail's comment about inlining the template functions led me to put the bodies back inside the class body. This eliminated the problem. Embarassingly, the problem was that outside the class I had "template <typename> void MyFunction1 (...)" instead of "template <typename> void MyClass::MyFunction1 (...)". MyFunction1 was the only template member function for which I made this mistake, which is why MyFunction2 (and others) worked fine. The usual cut-and-paste-and-forget-to-finish-the-job problem. Well, there went most of a day due to a careless error...

Thanks for the feedback.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this