开发者

Template class giving linker error

I am having a template class which is exposed, in which I added a method. This class is in namespace A. Now, I am calling this method in another namespace (say B). Initially, compiler gave me linker error saying "unresolved external symbol" for this particular method.

However, if I call this method inside the same namespace (that is A), it links well. After that, it links well in namespace B as well.

Why could this be happening ?

Does this has something to do with the creating Template object of my class ?

Atul

Here is the code snippet ...

namespace sss  
{  
    namespace AAA  
    {
        template <<typename T, typename TAlloc = Allocator< T > > 
        class DLL_EXPORT A  
        {  
             public:
             // Some other functions that are working fine ...
             bool fooA() const;  
             {  
                  return Size()>0;  
             }  
        };  
    }  
}  


//I get a linker error when I call it in another namespace (say B)...  
//I am accessing this method in public method of some other class in namespace B  

// Including the header for class A ...
#include A.h

namespace QQQ  
{  
    namespace B  
    {  
        class B
        {
            private:  
            AAA::A obj; // Object of class A ...
            public:  
            // SOme methods 
            // Method that calls fooA ...
            GetResult()
            { 
                fooA // This causes causes linker error when i call it here, 
                     // but, it works when i call it in namespace AAA, 
                     // and then it, it works here as well   
            } 
        };

When I am calling this method from within namespace B, it gives unresolved 开发者_开发问答external symbol, but, when i call this from within namespace A, it links well in A, and again in B as well.

Any ideas ?


It's probably the usual problem: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13.


You're using the templated class incorrectly. The following should work:

namespace QQQ  
{  
    namespace B  
    {
        class B
        {
            // Note the template parameter (int)
            AAA::A<int> obj;

            public:
            bool GetResult() const
            {
                // Note the parentheses and the "obj"
                return obj.fooA()
            } 
        };
    }
}

The only problem I can imagine with this code would be the ambiguity between the B namespace and the B class, but a fully qualified call (QQQ::B::B) should work.


According to your symptom (linker error when called from namespace other than A, but no linker errors if also called from namespace A), then -- assuming that your syntax is correct in your actual code -- your problem is that you're not correctly instantiating the template. Templates are compile time constructs, and as such they really can't be compiled into DLLs. Instead, the template must be correctly instantiated at compile time. When you don't get linking errors it's because the template is correctly instantiated, and when you do get linking errors it's because it hasn't been.

Because of the DLL_EXPORT symbol I assume that you're using Visual C++. Even so, the GCC guys have a good write-up that applies to Visual Studio as well. Most templated libraries I'm familiar with (such as Boost) require all templates be declared and defined in the header file. It's also legitimate to explicitly instantiate the templates, as recommended by the GCC guys.


I had the same problem with Borland 5 Professional. I got an linker error with external reference message. The solution was to include the .cpp file at the end of your header. Because the compiler needs to have the full definition to be able to instantiate a template. Therefore, it must be defined in the translation unit you want to use it in.

Hope that helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜