Kelas templat memberikan kesalahan tautan


Saya memiliki kelas templat yang terbuka, di mana saya menambahkan metode. Kelas ini berada di namespace A. Sekarang, saya memanggil metode ini di namespace lain (misalnya B). Awalnya, kompiler memberi saya kesalahan linker yang mengatakan "simbol eksternal yang belum terselesaikan" untuk metode khusus ini.
Namun, jika saya memanggil metode ini di dalam namespace yang sama (yaitu A), metode ini tertaut dengan baik. Setelah itu, ia juga terhubung dengan baik di namespace B.
Mengapa ini bisa terjadi?
Apakah ini ada hubungannya dengan pembuatan objek Templat di kelas saya?
Atul
Ini kodenya cuplikan ...

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

Ketika saya memanggil metode ini dari dalam namespace B, ia memberikan simbol eksternal yang belum terselesaikan, namun, ketika saya memanggil ini dari dalam namespace A, ia tertaut dengan baik di A, dan lagi di B juga.
Ada ide?


person Atul    schedule 03.01.2011    source sumber
comment
Bisakah Anda memberikan contoh kode minimal yang menunjukkan hal ini?   -  person Oliver Charlesworth    schedule 03.01.2011
comment
Saya hanya ingin tahu apa arti namespace templateet?   -  person UmmaGumma    schedule 03.01.2011
comment
Saya telah menambahkan cuplikan kodenya, terima kasih   -  person Atul    schedule 03.01.2011
comment
Namun dalam kode ini tidak ada namespace B. Harap berikan cuplikan kode di ideone.com.   -  person Pawel Zubrycki    schedule 03.01.2011
comment
Saya menambahkan kode lagi Pawel, saya baru mengenal STL ini ...   -  person Atul    schedule 04.01.2011


Jawaban (3)


Ini mungkin masalah biasa: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13.

person Oliver Charlesworth    schedule 03.01.2011

Anda salah menggunakan kelas templat. Berikut ini seharusnya berfungsi:

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

Satu-satunya masalah yang dapat saya bayangkan dengan kode ini adalah ambiguitas antara namespace B dan kelas B, tetapi panggilan yang sepenuhnya memenuhi syarat (QQQ::B::B) akan berfungsi.


Menurut gejala Anda (kesalahan tautan saat dipanggil dari namespace selain A, tetapi tidak ada kesalahan tautan jika juga dipanggil dari namespace A), lalu -- dengan asumsi sintaksis Anda benar dalam kode sebenarnya -- masalah Anda adalah Anda tidak membuat instance template dengan benar. Templat adalah konstruksi waktu kompilasi, dan karenanya tidak dapat dikompilasi menjadi DLL. Sebaliknya, templat harus dibuat dengan benar pada waktu kompilasi. Bila Anda tidak mendapatkan kesalahan penautan, itu karena templat dibuat dengan benar, dan bila Anda mendapatkan kesalahan penautan, itu karena belum terjadi.

Karena simbol DLL_EXPORT saya berasumsi Anda menggunakan Visual C++. Meski begitu, tim GCC memiliki tulisan bagus yang dapat diterapkan pada Visual Studio juga. Sebagian besar perpustakaan templat yang saya kenal (seperti Boost) mengharuskan semua templat dideklarasikan dan didefinisikan dalam file header. Sah juga untuk membuat contoh template secara eksplisit, seperti yang direkomendasikan oleh orang-orang GCC.

person Max Lybbert    schedule 04.01.2011

Saya memiliki masalah yang sama dengan Borland 5 Professional. Saya mendapat kesalahan tautan dengan pesan referensi eksternal. Solusinya adalah dengan menyertakan file .cpp di akhir header Anda. Karena compiler harus memiliki definisi lengkap untuk dapat membuat instance template. Oleh karena itu, ini harus didefinisikan dalam unit terjemahan tempat Anda ingin menggunakannya.

Semoga itu bisa membantu.

person Jonny Schubert    schedule 05.04.2012