使用模板时出现未解决的外部问题

3

我正在将运算符重载与模板类混合使用,并达到了以下的赋值:

j = end - begin;

在我的主函数中,变量类型如下:
ptrdiff_t j;
util::BaseArrayIterator<int, 6> begin, end;

从util::BaseArray初始化了Begin和End:

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
由于消息中的第一条代码语句(删除它可以解决问题),请注意保留HTML标签。我已经包含了一个带有以下定义和声明的头文件:
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::operator -,所以它找到了声明,但没有找到定义,尽管它们在同一个文件中。我看不到签名错误。
--- 编辑说明 ---
替换
end-begin

使用

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

解决了这个问题,但我不想每次都明确指定参数。简洁是支持重载运算符的主要论点之一,因此我希望使用经典的简短形式。
--- 编辑注释2 --- 如Nicola Mussatti所示,[解决方案]:Unresolved external symbol with operator overloading and templates,问题在于友元声明应该移动到类内部。 所以我这样做了,我很开心。 现在将它们分开会出现模棱两可的重载问题,这与以前的错误不同。

尝试将声明放在与定义不同的文件中。在C++中,模板是非常微妙的东西。只需尝试更改事物,直到它正常工作即可。 - Daniel
1
将声明和定义分开只会使情况更糟。 - Puppy
可能是定义在命名空间之外了吗?或者是}放错位置了? - Bo Persson
我的代码片段中缺少了一个闭合的}。我已经添加了它。 - Tetelu
这个问题的答案似乎证实了我的评论。 - Nicola Musatti
显示剩余2条评论
1个回答

0
你使用哪个编译器?
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;
}

我正在使用VS2005。可能编译器不是问题的原因。 - Tetelu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接