2014-12-14 2 views
0

У меня есть проект, все мои классы, templated для int, double и float, getCoordinate возвращают объект типа CCoordinate.operator = Перегрузка с шаблоном класса

  tempCoordinate = m_shapes.at(i)->getCoordinate(j); 

Прежде чем применять шаблоны, он работает правильно. Но затем появляются некоторые ошибки.

Из того, что я понимаю, что должен я пропускаю и оператор = перегрузка в типаж значения в случае, например, что у меня есть поплавок и Я получаю Int, например:

 CCoordinate<float> coorFloat; 
     CCoordinate<int> coorInt = coorFloat 

Как могу ли я создать это на моем классе? какой формат нужен? ,

Я думал, что это должно выглядеть так, но, видимо, я ошибаюсь.

//CCoordinate.h 
template<class T> 
class CCoordinate { 
//Code 
public: 
template<class U> template <class U> CCoordinate<T> 
      operator= (const CCoordinate<U>& c1); 
} 

//CCoordinate.cpp 
template <class U > 
CCoordinate<U> CCoordinate<T>::operator= (const CCoordinate<U>& c1) 
{ 
    // some kind of casting ? 
} 

Мои ошибки:

19:06:43 **** Incremental Build of configuration Debug for project ShapesRefV2 **** 
Info: Internal Builder is used for build 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -Werror=return-type -o "myCode\\CRectangle.o"  "..\\myCode\\CRectangle.cpp" 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -Werror=return-type -o "myCode\\CPlane.o" "..\\myCode\\CPlane.cpp" 
..\myCode\CPlane.cpp: In instantiation of 'GraSys::CRectangle<T>  GraSys::CPlane<T>::boundingBox(std::string, std::string) [with T = int; std::string = std::basic_string<char>]': 
..\myCode\CPlane.cpp:165:24: required from here 
..\myCode\CPlane.cpp:115:20: error: no match for 'operator=' (operand types are 'GraSys::CCoordinate<double>' and 'const GraSys::CCoordinate<int>') 
    tempCoordinate = m_shapes.at(i)->getCoordinate(j); 
       ^
..\myCode\CPlane.cpp:115:20: note: candidate is: 
In file included from ..\myCode\CGraphicElement.h:14:0, 
       from ..\myCode\CPlane.h:11, 
       from ..\myCode\CPlane.cpp:9: 
..\myCode\CCoordinate.h:17:7: note: GraSys::CCoordinate<double>& GraSys::CCoordinate<double>::operator=(const GraSys::CCoordinate<double>&) 
class CCoordinate 
     ^
..\myCode\CCoordinate.h:17:7: note: no known conversion for argument 1 from 'const GraSys::CCoordinate<int>' to 'const GraSys::CCoordinate<double>&' 
..\myCode\CPlane.cpp: In instantiation of 'GraSys::CRectangle<T> GraSys::CPlane<T>::boundingBox(std::string, std::string) [with T = float; std::string = std::basic_string<char>]': 
..\myCode\CPlane.cpp:166:24: required from here 
..\myCode\CPlane.cpp:115:20: error: no match for 'operator=' (operand types are 'GraSys::CCoordinate<double>' and 'const GraSys::CCoordinate<float>') 
    tempCoordinate = m_shapes.at(i)->getCoordinate(j); 
        ^
..\myCode\CPlane.cpp:115:20: note: candidate is: 
In file included from ..\myCode\CGraphicElement.h:14:0, 
       from ..\myCode\CPlane.h:11, 
       from ..\myCode\CPlane.cpp:9: 
..\myCode\CCoordinate.h:17:7: note: GraSys::CCoordinate<double>& GraSys::CCoordinate<double>::operator=(const GraSys::CCoordinate<double>&) 
class CCoordinate 
    ^
..\myCode\CCoordinate.h:17:7: note: no known conversion for argument 1 from 'const GraSys::CCoordinate<float>' to 'const GraSys::CCoordinate<double>&' 

19:06:44 Build Finished (took 674ms) 
+1

Сначала [переместите все определения шаблонов в заголовок] (http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). –

+0

hint: operator = должен возвращать ссылку на класс, в котором он живет. –

ответ

3

В объявлении члена вы имеете template <class U> слишком много раз, а член должен возвращать ссылку на *this, поэтому он должен вернуть CCordinate & (<T> подразумевается, если вы его опускаете):

// Remove this  vvvvvvvvvvvvvvvvvv 
template<class U> /* template <class U> */ 
CCoordinate & operator= (const CCoordinate<U>& c1); 
//   ^- Return type changed to be a reference. 

Поскольку элемент является шаблоном, а класс является шаблоном, у вас есть два уровня te mplates. Вы должны указать оба уровня при реализации элемента.

Он также возвращает неправильный тип (он возвращает CCoordinate<U>, но вы заявили, что он возвращает CCoordinate<T> в классе).

// You need the T template as well. 
// vvvvvvvvvvvvvvv 
template <class T> 
template <class U> 
CCoordinate<T> & CCoordinate<T>::operator= (const CCoordinate<U>& c1) 
//  ^^- Added reference as per above. 
//   \---- Changed to T; U makes no sense here and conflicts with your member 
//    declaration in the class. 
{ 
    // Your logic to make the conversion. 

    return *this; 
} 
+0

компилируется, но чего-то не хватает. undefined ссылка на 'GraSys :: CCoordinate & GraSys :: CCoordinate :: operator = (GraSys :: CCoordinate const &) ' – IzonFreak

+0

@IzonFreak Реализации шаблонов должны быть в заголовке, чтобы компилятор мог создавать их, когда они используются , Вероятно, вы поместите его в файл '.cpp'. [Вы не можете этого сделать] (http://stackoverflow.com/q/495021/501250) (если вы явно не создаете экземпляр для всех параметров типа, которые вам нужны, но я сомневаюсь, что вы это делаете, и вы не хотите в любом случае). – cdhowie

0

У вас возникли две проблемы. Более простая проблема заключается в том, что синтаксис объявления вашего operator= имеет дополнительные template <class U>. Он должен выглядеть следующим образом:

template<class U> CCoordinate<T> 
      operator= (const CCoordinate<U>& c1); 

Однако даже правильно определили operator= не позволит писать

CCoordinate<float> coorFloat; 
CCoordinate<int> coorInt = coorFloat; 

Это происходит потому, что вторая линия выше copy initializescoorInt. operator= не рассматривается для инициализации копии - он смотрит только на user-defined conversions, который включает в себя только не явные конструкторы и неявные функции преобразования в этом случае.

Смежные вопросы