Класс шаблона с ошибкой компоновщика - PullRequest
1 голос
/ 03 января 2011


У меня есть шаблонный класс, в котором я добавил метод.Этот класс находится в пространстве имен A. Теперь я вызываю этот метод в другом пространстве имен (скажем, B).Первоначально компилятор дал мне ошибку компоновщика, говоря «неразрешенный внешний символ» для этого конкретного метода.
Однако, если я вызываю этот метод в том же пространстве имен (то есть A), он хорошо связывается.После этого он также хорошо связывается в пространстве имен B.
Почему это может происходить?
Это как-то связано с созданием объекта Template моего класса?
Atul
Вот кодфрагмент ...

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   
            } 
        };

Когда я вызываю этот метод из пространства имен B, он дает неразрешенный внешний символ, но, когда я вызываю этот метод из пространства имен A, он хорошо связывается в A и сноваБ, а также.
Есть идеи?

Ответы [ 3 ]

2 голосов
/ 03 января 2011

Это, наверное, обычная проблема: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13.

0 голосов
/ 05 апреля 2012

У меня была такая же проблема с Borland 5 Professional. Я получил ошибку компоновщика с внешним справочным сообщением. Решением было включить файл .cpp в конец заголовка. Потому что у компилятора должно быть полное определение, чтобы можно было создать экземпляр шаблона. Следовательно, он должен быть определен в той единице перевода, в которой вы хотите его использовать.

Надеюсь, это поможет.

0 голосов
/ 04 января 2011

Вы используете шаблонный класс неправильно.Должно работать следующее:

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()
            } 
        };
    }
}

Единственная проблема, которую я могу себе представить с этим кодом, - это неоднозначность между пространством имен B и классом B, но полностью квалифицированный вызов (QQQ::B::B)должно работать.


В соответствии с вашим симптомом (ошибка компоновщика при вызове из пространства имен, отличного от A, но нет ошибок компоновщика, если также вызывается из пространства имен A), тогда - при условии, что ваш синтаксисправильно в вашем реальном коде - ваша проблема в том, что вы не правильно создаете экземпляр шаблона.Шаблоны являются конструкциями времени компиляции, и поэтому они действительно не могут быть скомпилированы в DLL.Вместо этого шаблон должен быть правильно создан во время компиляции.Когда вы не получаете ошибок компоновки, это потому, что шаблон правильно создан, а когда вы получаете ошибки компоновки, это потому, что его не было.

Из-за символа DLL_EXPORT я предполагаю, что выиспользуя Visual C ++.Тем не менее, у ребят из GCC есть хорошая запись , которая также применима к Visual Studio.Большинство шаблонных библиотек, с которыми я знаком (например, Boost), требуют, чтобы все шаблоны были объявлены и определены в заголовочном файле.Также допустимо явно создавать экземпляры шаблонов, как рекомендовано ребятами из GCC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...