Question

I have a class inheriting from two classes, one which is my own base class, and a template class:

typedef typename cusp::csr_matrix< int,
                                   float,
                                   cusp::host_memory > csr_matrix;

class CuspMatrix
: 
  public csr_matrix,
  public Matrix
{
...
}

At some point, I have to do an assignment, which will copy the base class object from the host to the device like so:

cusp::csr_matrix<int,float,cusp::host_memory> A(4,3,6);
cusp::csr_matrix<int,float,cusp::device_memory> A = B;

but before I can do that, I have to upcast my this to its base class csr_matrix

I've tried with static_cast and a custom cast operator:

operator csr_matrix()
{
  return *( cusp::csr_matrix< int,float,cusp::device_memory> *)this;
}

However, when I try to do the actual thing, I get tons of errors from the compiler

cusp::csr_matrix<int,float,cusp::device_memory> mtx = *(csr_matrix *)this;

In fact, static casting also is beyond me at this point:

auto me = static_cast<csr_matrix>( *this );
cusp::csr_matrix<int,float,cusp::device_memory> mtx = me;

yet, a C-style shotgun cast without the typedef, seems to work:

auto me = *( cusp::csr_matrix< int,
                               float,
                               cusp::host_memory> *)this;

but fails with the typedef:

auto me = *( csr_matrix *)this;
  • So, How can I safely up-cast using my own custom operator, preferably by using a static cast?

  • Why does casting with the full namespace::type work, yet fail with the typedef?

Was it helpful?

Solution

cusp::csr_matrix<int,float,cusp::device_memory> mtx = *(csr_matrix *)this;

This cast can never call a conversion function because the type of the operand this of the cast expression is CuspMatrix*. A conversion function will only be considered when the type of the operand is a class type:

cusp::csr_matrix<int,float,cusp::device_memory> mtx = (csr_matrix)*this;

In this scenario, csr_matrix is already a public base class of CuspMatrix - so the conversion function CuspMatrix::operator csr_matrix(), can never be called.

This upward-conversion does not require a cast - when this is of type CuspMatrix* and cusp::csr_matrix<int,float,cusp::device_memory> supports assignment from cusp::csr_matrix<int,float,cusp::host_memory>, you should be able to do this:

cusp::csr_matrix<int,float,cusp::device_memory> mtx = *this;

Without seeing the actual error messages and a compilable example, it's difficult to answer the second question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top