使用模板时未解析的外部

Unresolved external when using templates

本文关键字:外部      更新时间:2023-10-16

我将操作符重新定义与模板类混合,并达到以下赋值:

j = end - begin;

,其中变量类型如下:

ptrdiff_t j;
util::BaseArrayIterator<int, 6> begin, end;

开始和结束已经从util::BaseArray:

初始化
util::BaseArray<int, 6> ba(SOME_PARAMETERS);
begin = ba.begin(); end = ba.end();

BaseArrayIterator是一个自实现的迭代器类型。

我得到错误:

TestProject.obj : error LNK2019: unresolved external symbol
"int __cdecl util::operator-(class util::BaseArrayIterator<int,6>
const &,class util::BaseArrayIterator<int,6> const &)" 
(??Gutil@@YAHABV?$BaseArrayIterator@H$05@0@0@Z) referenced in
function _main

由于消息中的第一个代码语句(删除它可以修复问题)。

我包含了一个头文件,其中包含以下定义和声明:

namespace util {
template<typename T, int n>
typename BaseArrayIterator<T,n>::difference_type operator -
    (const BaseArrayIterator<T,n> &itL,
     const BaseArrayIterator<T,n> &itR);
...
template<typename T, int n>
typename BaseArrayIterator<T,n>::difference_type operator -(
    const BaseArrayIterator<T,n> &itL, 
    const BaseArrayIterator<T,n> &itR)
{   return -(itL.m_cnt - itR.m_cnt);
}
}

问题的原因是什么?编译器报告搜索util::操作符-,所以他找到了声明,但没有找到定义,尽管它们在同一个文件中。我没有看到签名错误。

——编辑注 -----------------------------------------------------------------------------

替换

end-begin

util::operator-<int, 6>(end,begin)

解决了这个问题,但是我不想每次都显式地指定参数。简洁是支持重载操作符的主要参数之一,所以我想使用经典的简短形式。

——编辑注2 ---------------------------------------------------------------------------

正如Nicola Mussatti善意指出的那样,[解决方案]:未解决的外部符号与操作符重载和模板的问题在这里。友元声明应该移到类内部。

所以我做了,我微笑着。现在将它们分开会再次产生歧义的重载问题,这与之前的错误不同。

您使用的是哪个编译器?

VS2010很满意这段代码:

namespace util
{
    template<typename T>
    class BaseArrayIterator
    {
    public:
        typedef ptrdiff_t difference_type;
        int pos;
        T x;
    };
    template<typename T>
    typename BaseArrayIterator<T>::difference_type operator -
        (const BaseArrayIterator<T> &itL,
         const BaseArrayIterator<T> &itR);
    template<typename T>
    typename BaseArrayIterator<T>::difference_type operator -
        (const BaseArrayIterator<T> &itL,
         const BaseArrayIterator<T> &itR)
    {
        return itL.pos - itR.pos;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    util::BaseArrayIterator<int> a;
    util::BaseArrayIterator<int> b;
    ptrdiff_t dist = a - b;
    return 0;
}