0

I have a project will all my classes templated for int, double and float, getCoordinate return an object of the type CCoordinate.

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

Before I apply the templates it was working correctly. But then some errors appear.

From what I understand I need I'm missing and operator= overload to typecast the values in case for example that i have a float and I'm receiving an int, for example:

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

How can i create this on my class? what format does it need ? .

I was thinking that it should look like this, but apparently i'm mistaken.

//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 ? 
}

My Errors:

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)
IzonFreak
  • 409
  • 1
  • 5
  • 15

2 Answers2

3

In the member declaration you have template <class U> too many times, and the member should return a reference to *this, so it needs to return CCordinate & (the <T> is implied if you omit it):

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

Since the member is a template and the class is a template, you have two levels of templates. You need to specify both levels when you implement the member.

It is also returning the wrong type (it returns CCoordinate<U> but you have declared it to return CCoordinate<T> in the class).

// 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;
}
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • it compiles, but something is missing. undefined reference to `GraSys::CCoordinate& GraSys::CCoordinate::operator=(GraSys::CCoordinate const&)' – IzonFreak Dec 14 '14 at 18:54
  • @IzonFreak Template implementations need to be in the header so the compiler can instantiate them when they are used. You probably put it in a `.cpp` file. [You can't do that](http://stackoverflow.com/q/495021/501250) (unless you explicitly instantiate for all type parameters you need, but I doubt you are doing that and you don't want to anyway). – cdhowie Dec 14 '14 at 18:57
0

There are two issues with your attempt. The simpler issue is that the declaration syntax of your operator= has an extra template <class U>. It should look like this:

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

However, even a correctly defined operator= will not allow you to write

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

This is because the second line above copy initializes coorInt. operator= is not considered for copy initialization - it only looks at user-defined conversions which only include non-explicit constructors and non-explicit conversion functions in this case.

Pradhan
  • 16,391
  • 3
  • 44
  • 59