Search code examples
c++castingtype-conversion

Is there a canonical way to handle explicit conversion between two externally-defined classes?


I'm using two external libraries which define classes with identical contents (let's say Armadillo's Arma::vec and Eigen's Eigen::VectorXd). I would like to be able to convert between these classes as cleanly as possible.

If I had defined either class, it would be trivial to include a constructor or conversion operator in that class' definition, to allow me to write e.g.

Arma::vec foo(/*some constructor arguments*/);
Eigen::VectorXd bar = Eigen::VectorXd(foo);

but since both classes are from external libraries, I cannot do this. If I attemt to write a naive conversion function, e.g.

class A{
public:
  int value_;
  A(int value) : value_(value) {}
};

class B{
public:
  int value_;
  B(int value) : value_(value) {}
};

A A(const B& b){return A(b.value_);}

int main(void){
  A a(1);
  B b(2);
  a = A(b);
}

then the function shadows the class definition, and suddenly I can't use the A class at all.

I understand that allowing A a=b to be defined would be a bad idea, but I don't see why allowing A a=A(b) would cause any problems.

My question:

Is it possible to write a function or operator to allow the syntax A a=A(b)? And if not, is there a canonical way of doing this kind of conversion?

I've seen A a=toA(b) in a few libraries, but this isn't used consistently, and I dislike the inconsistency with the usual type conversions.


Solution

  • Is it possible to write a function or operator to allow the syntax A a=A(b)?

    No, it is not possible. The two classes involved define what conversions are possible and you can't change a class definition after it has been defined.

    You will need to use a function as in your given example, although I would avoid repeating the type name and write

    auto a = toA(b);