我有一个暴露的模板类,我在其中添加了一个方法。这个类在命名空间A中。现在,我在另一个命名空间中调用此方法(比如说B)。最初,编译器给了我链接器错误,说明这个特定方法的“未解析的外部符号”
但是,如果我在同一名称空间(即A)中调用此方法,则链接很好。之后,它也在命名空间B中很好地链接
为什么会发生这种情况?
这是否与我班级的模板对象有关?
阿图尔
这是代码片段......
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中很好地链接,在B中也是如此。 有任何想法吗 ?
答案 0 :(得分:2)
答案 1 :(得分:0)
您正在错误地使用模板化类。以下应该有效:
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 ++。即便如此,海湾合作委员会成员也有good write-up也适用于Visual Studio。我熟悉的大多数模板库(例如Boost)都要求在头文件中声明和定义所有模板。根据GCC人员的建议,显式实例化模板也是合法的。
答案 2 :(得分:0)
我和Borland 5 Professional有同样的问题。我收到外部参考消息的链接器错误。解决方案是在标题的末尾包含.cpp文件。因为编译器需要具有完整定义才能实例化模板。 因此,必须在要使用它的翻译单元中定义它。
希望有所帮助。