Alexandre Maneta
Alexandre Maneta

Reputation: 99

How do is resolve conversion error from Point<T> to non scalar Point<U>

I've stumbled upon a problem and I can't seem to find any information on SO on how to solve it. I've created a generic Point class and I'd like to convert from one to another. However, the compiler is always giving me the same error.

template<typename T>class Point                                       
{                                         
    private:                                          
    T m_x, m_y;                                       
    public:                                       
    Point(): m_x(1), m_y(1){}                                         
                                          
    Point(T x, T y): m_x(x), m_y(y){}                                         
                                          
    void scale(T k){                                          
        this->m_x *= k;                                       
        this->m_y *= k;                                       
    }                                         
    void add(Point<T> p){                                         
        this->m_x += p.getX();                                        
        this->m_y += p.getY();                                        
    }                                         
    T getX() const{                                       
        return this->m_x;                                         
    }                                         
    T getY() const{                                       
        return this->m_y;                                         
    }                                         
    void setX(T x){                                       
        this->m_x = x;                                        
    }                                         
    void setY(T y){                                       
        this->m_y = y;                                        
    }                                         
                                          
    template<class U>                                         
    void add(Point<U> p){                                         
        this->m_x += p.getX();                                        
        this->m_y += p.getY();                                        
    }                                                                             
                                          
    template<class U>                                         
    Point<U>& operator=(const Point<T>& p){                                       
        this->m_x = p.getX();                                         
        this->m_y = p.getY();                                         
        return *this;                                         
    }                                         
                                          
                                          
};                                        
                                          
                                          
                                          
typedef Point<int> Pointi;                                        
typedef Point<float> Pointf;                                          
typedef Point<double> Pointd;

int main(int argc, char** argv){
    Pointi pi(1,7);
    Pointd pd = pi;
    return 0;
}

This is the error I have whenever I compile.

error: conversion from ‘Point<int>’ to non-scalar type ‘Point<double\o>’ requested Pointd pd = pi;

Upvotes: 2

Views: 108

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117318

You've already gotten the answer you need, but I'll add some notes that may spare you some time when implementing the operators.

Point<int>, Point<float> and Point<double> are all unrelated types and there is no implicit conversion between them.

For conversion to happen you can add a conversion (or converting) constructor:

template <class U>
Point(const Point<U>& other) :
    m_x(other.getX()),
    m_y(other.getY())
{} 

With that implicit conversion constructor in place, the below would work, even without your converting assignment operator (template<class U> Point<U>& operator=(const Point<T>& p)):

Pointi pi(1,7);
Pointd pd;
pd = pi;

pi would here be converted to a Pointd which would be used to move assign pd.

Upvotes: 1

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122585

Often confused: Pointd pd = pi; is not calling the assignment operator! It is initialisation not assignment. You can add a constructor like this to make your code compile:

template <class U>
Point(const Point<U>& other) : m_x(other.getX()),m_y(other.getY()) {}                              

Live Demo

Upvotes: 4

Related Questions