I have a class templated on a floating point type,
template <typename fl_t> class generic {
fl_t a,b;
/// a bunch of getters and setters, etc...
}
and instantiate with float and double
typedef generic<double> dmatrix;
typedef generic<float> fmatrix;
Later, when I want to assign an fmatrix to a dmatrix, I get
error: no viable conversion from 'const generic<float>' to 'generic<double>'
note: candidate constructor (the implicit copy constructor) not viable:
no known conversion from 'const fmatrix' (aka 'const generic<float>')
to 'const generic<double> &' for 1st argument
template <typename fl_t> class generic {
I wrote an overloaded assignment:
template <typename f> generic<f>& operator= ( const generic& g){
aSET(g.aGET(); // etc
return *this;
}
This compiles but does not solve the problem. Why? Must I write a cast and with what signature?
CodePudding user response:
Your assignment operator takes the current type as parameter:
template <typename fl_t> class generic {
// ...
template <typename f> generic<f>& operator=(const generic& g)
// this is generic<fl_t> ^^^^^^^
// ...
};
If you want to assign from another type, you need to swap the return type and the parameter type:
template <typename f> generic& operator=(const generic<f>& g)
The type of the parameter is the type of the variable you want to assign from. The return type can be whatever you want, but for an assignment operator it's typically a reference to the type of the variable you want to assign to (that's the current class) so that you can do something else directly with the result, for example chain assignments (a = b = c
).
If you don't want the conversion to be implicit (in other words, if you want the assignment to require a cast), you can mark the operator explicit:
template <typename f> explicit generic& operator=(const generic<f>& g)