正确实例化的模板方法调用未解析的NON模板方法

时间:2015-12-02 15:51:06

标签: c++ visual-studio-2010 templates unresolved-external

在决定提出这个问题之前,我搜索了整个互联网和堆栈溢出,所以如果我忽略了一些非常简单的事情,请原谅,但是现在就这样了。

使用Visual Studio 2010,我得到了这样一个类:

class MyClass {
public:
    /* Constructors and other methods omitted */

    template <typename T1>
    CString operator()(const T1 &a1) { return _fmt("dummy", a1); }

    template <typename T1, typename T2>
    CString operator()(const T1 &a1, const T2 &a2) { return _fmt("dummy", a1, a2); }

    template <typename T1, typename T2, typename T3>
    CString operator()(const T1 &a1, const T2 &a2, const T3 &a3) { return _fmt("dummy", a1, a2, a3); }

    template <typename T1, typename T2, typename T3, typename T4>
    CString operator()(const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4) { return _fmt("dummy", a1, a2, a3, a4); }

private:    
    CString _fmt(const char *dummy, ...);
};

我们的想法是为MyClass提供一个operator ()重载,其作用类似于sprintf()格式化程序,但格式字符串包含在MyClass实例本身中。我会使用可变参数模板,但是Visual Studio 2010并不支持它们,因此半生不熟的解决方案是提供许多operator ()的过载模板版本,而这些版本又会调用私有_fmt()函数它使用va_list/va_start()/va_end()因此需要强制使用无用的第一个参数(因此名称为&#34; dummy&#34; )。

编译很顺利,但链接会产生如下错误:

error LNK2019: unresolved external symbol "private: class ATL::CStringT<char,class ATL::StrTraitATL<char,class ATL::ChTraitsCRT<char> > > __cdecl MyClass::_fmt(char const *,...)" (?_fmt@MyClass@@AAA?AV?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@@PBDZZ) referenced in function "public: class ATL::CStringT<char,class ATL::StrTraitATL<char,class ATL::ChTraitsCRT<char> > > __thiscall MyClass::operator()<char [261]>(char const (&)[261])" (??$?R$$BY0BAF@D@MyClass@@QAE?AV?$CStringT@DV?$StrTraitATL@DV?$ChTraitsCRT@D@ATL@@@ATL@@@ATL@@AAY0BAF@$$CBD@Z)

我从上面的消息中理解的是,模板化运算符已被正确实例化,并且它包含对_fmt()方法的调用,但是,链接器无处可寻。

但是_fmt() 包含在.cpp文件中,其中 正在编译和喜欢,实际上构造函数也在那里定义,并且链接器没有& #39;抱怨它。

我发现解决这个问题的唯一方法是将_fmt()代码放在头文件中的类定义主体中,这相当丑陋。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

好吧,这是一个愚蠢的,但由于其他人可能会以某种方式偶然发现它,我正在回答我自己的问题。

我错误地包含了头文件<afxmt.h>,它是MFC的一部分,以便获得CCriticalSection类定义,而项目的其余部分使用ATL,这带来了不同版本的CString。但不知何故,这只影响了MyClass实现文件,而其他人,即使他们使用的是MyClass,也得到了不同版本的CString。

我通过不包括<afxmt.h>并自己实施CCriticalSection课程解决了这个问题。