1

all. I am trying to learn something about template inherit. I want to cast a temp derived object to its base reference. But I come across this problem:

typedef long size64_t;
//////Base class
template <typename _Scalar>
class MatrixBase{
public:
    virtual _Scalar operator()(size64_t rowid, size64_t colid) = 0;
};
//////Derived class 1
template <typename _Scalar>
class MatrixHolder : public MatrixBase<_Scalar>{
public:
    MatrixHolder(){};
    inline _Scalar  operator()(size64_t rowid, size64_t colid){return 0;}
};

//////Derived class 2
template <typename _Scalar>
class Matrix : public MatrixBase<_Scalar>{
public:
    Matrix(){};
    inline _Scalar  operator()(size64_t rowid, size64_t colid){return 0;}
};
//////The function with parameters as Base class reference, wanting to get derived object as input.
template <typename _Scalar>
MatrixHolder<_Scalar> apply(MatrixBase<_Scalar>& lhs, MatrixBase<_Scalar>& rhs){
    MatrixHolder<_Scalar> result;
    return result;
}

and in main, we have:

void main(){
    Matrix<double> m1;
    Matrix<double> m2;
    apply(m1, m2);//Sucess
    apply(m1, apply(m1, m2));//Fail
}

the compiler said:

note: candidate function [with _Scalar = double] not viable: no known conversion from
      'MatrixHolder<double>' to 'MatrixBase<double> &' for 2nd argument
MatrixHolder<_Scalar> apply(MatrixBase<_Scalar>& lhs, MatrixBase<_Scalar>& rhs){
                      ^
1 error generated.
maple
  • 1,828
  • 2
  • 19
  • 28
  • I think your problem is to use double as the template argument. As shown here http://stackoverflow.com/questions/2183087/why-cant-i-use-float-value-as-a-template-parameter to seems not to be possible – Stefan Reinhardt Mar 04 '16 at 10:14
  • 1
    You're trying to bind a non-const reference to a temporary object. Make the parameters to `apply` const references. – molbdnilo Mar 04 '16 at 10:15
  • @molbdnilo do you mean that all the temp object should be const? – maple Mar 04 '16 at 10:18
  • @maple No, the function's parameters should be; `const MatrixBase<_Scalar>& rhs`. (This has nothing to do with either templates or inheritance, by the way.) – molbdnilo Mar 04 '16 at 10:23
  • 1
    @StefanReinhardt Using the *type* double as a template parameter is not a problem. The problem you linked to is using floating-point *values* as template parameters. – molbdnilo Mar 04 '16 at 10:26
  • @molbdnilo Ahh sry my fault of course you're right i was too fast with my conclusion because I got almost the same error when trying to use that a few days ago... – Stefan Reinhardt Mar 04 '16 at 10:28
  • Side note: Do not `typedef long size64_t`, just use `std::size_t` –  Mar 04 '16 at 10:35
  • @DieterLücking Can you tell me that in detail? Is there some links talking about this? – maple Mar 04 '16 at 10:50
  • @maple `std::size_t'` covers the maximum size possible. `long` might be shorter than 64 bits –  Mar 04 '16 at 10:54
  • @DieterLücking Thanks, it's really help. – maple Mar 04 '16 at 11:15

1 Answers1

1
apply(m1, apply(m1, m2));//Fail

The problem here is that the inner apply returns a temporary, which cannot bind to the non-const reference parameter of the outer apply.

If you can make the parameters MatrixBase<_Scalar> const& it would be a possible match.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203