Как реализовать перегрузку операторов в классе шаблона? - PullRequest
0 голосов
/ 10 ноября 2019

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

В моем .h у меня есть прямое объявление для класса и функции оператора, и я специально перегруженoperator+<T>, а не просто operator+, поэтому он работает для нескольких типов. Он прекрасно компилируется, когда я включаю только файл .h, но как только я пытаюсь объявить MyComplex<int>, появляются странные ошибки, которые мне трудно расшифровать.

my_complex.h:

#ifndef _MY_COMPLEX_H
#define _MY_COMPLEX_H

using namespace std;

//forward declarations
template<typename T> class MyComplex;

template<typename T> MyComplex<T> operator+(const MyComplex<T>& cmplx1, const MyComplex<T>& cmplx2);

template<typename T>
class MyComplex{
        private:
                T _real;
                T _imaginary;
        public:
                MyComplex();
                MyComplex(T real, T img);
                T getReal();
                T getImaginary();
                void setReal(T real);
                void setImaginary(T img);

                friend MyComplex operator+<T>(const MyComplex& cmplx1, const MyComplex& cmplx2);
}
#endif

my_complex.cpp:

#include "my_complex.h"
...
template <typename T>
MyComplex<T> operator+(const MyComplex<T>& cmplx1, const MyComplex<T>& cmplx2){
        MyComplex<T> temp;
        temp._real = cmplx1._real + cmplx2._real;
        temp._imaginary = cmplx1._imaginary + cmplx2._imaginary;

        return temp;
}
...

main.cpp:

#include "my_complex.h"

int main(int argc, char* argv[]){
        MyComplex<int> cmplx1 = MyComplex<int>(3, 5);//error is here
        MyComplex<int> cmplx2 = MyComplex<int>(5, 7);

        cmplx1 = cmplx1 + cmplx2;

        return 0;

}

Компилируется нормально, когда я включаю только файл .h в основной файл, но как толькоЯ пытаюсь объявить MyComplex<int>, что дает некоторые ошибки, которые мне трудно расшифровать.

In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                     from /usr/include/c++/7/bits/char_traits.h:39,
                     from /usr/include/c++/7/ios:40,
                     from /usr/include/c++/7/ostream:38,
                     from /usr/include/c++/7/iostream:39,
                     from main.cpp:1:
    /usr/include/c++/7/bits/stl_iterator.h: In instantiation of ‘class std::reverse_iterator<int>’:
    /usr/include/c++/7/bits/stl_iterator.h:400:5:   required by substitution of ‘template<class _Iterator> std::reverse_iterator<_Iterator> std::operator+(typename std::reverse_iterator<_Iterator>::difference_type, const std::reverse_iterator<_Iterator>&) [with _Iterator = int]’
    my_complex.h:36:20:   required from ‘class MyComplex<int>’
    main.cpp:8:17:   required from here
    /usr/include/c++/7/bits/stl_iterator.h:101:11: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<int>’
         class reverse_iterator
               ^~~~~~~~~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:115:55: error: no type named ‘difference_type’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::difference_type difference_type;
                                                           ^~~~~~~~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:116:48: error: no type named ‘pointer’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::pointer  pointer;
                                                    ^~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:117:50: error: no type named ‘reference’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::reference  reference;
                                                      ^~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h: In instantiation of ‘class std::move_iterator<int>’:
    /usr/include/c++/7/bits/stl_iterator.h:1201:5:   required by substitution of ‘template<class _Iterator> std::move_iterator<_IteratorL> std::operator+(typename std::move_iterator<_IteratorL>::difference_type, const std::move_iterator<_IteratorL>&) [with _Iterator = int]’
    my_complex.h:36:20:   required from ‘class MyComplex<int>’
    main.cpp:8:17:   required from here
    /usr/include/c++/7/bits/stl_iterator.h:1019:50: error: no type named ‘reference’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::reference  __base_ref;
                                                      ^~~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:1023:57: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::iterator_category iterator_category;
                                                             ^~~~~~~~~~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:1024:52: error: no type named ‘value_type’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::value_type   value_type;
                                                        ^~~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:1025:55: error: no type named ‘difference_type’ in ‘struct std::iterator_traits<int>’
           typedef typename __traits_type::difference_type difference_type;
                                                           ^~~~~~~~~~~~~~~
    /usr/include/c++/7/bits/stl_iterator.h:1032:24: error: no type named ‘reference’ in ‘struct std::iterator_traits<int>’
         __base_ref>::type  reference;
                            ^~~~~~~~~

1 Ответ

0 голосов
/ 10 ноября 2019

Вы не можете определить шаблонный метод в файле .cpp, поместите его в заголовок, и он должен работать. См. https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl

Кроме того, это

friend MyComplex operator+<T>(const MyComplex& cmplx1, const MyComplex& cmplx2);
// should match the forward declaration
friend MyComplex<T> operator+<>(const MyComplex<T>& cmplx1, const MyComplex<T>& cmplx2);

, поэтому вы должны добавить <T>

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

...