Неразрешенный внешний при использовании шаблонов - PullRequest
3 голосов
/ 07 августа 2011

Я смешиваю переопределение операторов с шаблонными классами и достигла следующего назначения:

j = end - begin;

в моей основной функции, где типы переменных следующие:

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

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 :: operator -, поэтому он нашел объявление, но не определение, хотя они находятся в одном файле.И я не вижу ошибки подписи.

--- РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ -----------------------------------------------------------------------------

Замена

end-begin

на

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

решает проблему, но я не хочу явно указывать параметры каждый раз.Сокращение - один из основных аргументов в пользу оператора перегрузки, поэтому я хотел бы использовать классическую краткую форму.

--- РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ 2 ---------------------------------------------------------------------------

Как любезно указал Никола Муссатти, [решение]: Неразрешенный внешний символ с перегрузкой оператора и шаблонами к проблеме находится здесь.Объявление друга должно быть перенесено в класс.

Так я и сделал, и все улыбаются.Теперь их разделение снова приводит к неоднозначным проблемам с перегрузкой, что не является той же ошибкой, что и раньше.

1 Ответ

0 голосов
/ 08 августа 2011

Какой компилятор вы используете?

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...