0

I have a template class hierarchy , I have to derived a class from an abstract one that declare :

template<typename T>
virtual T findValue(const std::size_t , const std::size_t ) const noexcept = 0;

But in the derived class my findValue method have different signature :

template<typename T>
T findValue(const std::size_t i, const std::size_t j, 
                      const std::size_t rBlock, const std::size_t cBlock
                     ) const noexcept ;

So what is the best way to make the derived class not abstract ?

of course I can define :

private:
 template<typename T>
  T findValue(const std::size_t r, const std::size_t c) const noexcept override 
{ return T(0) ;  } 

but I don't like this ! so what are better ways to doing so and working with derived class (not abstract of course)

EDIT in all the function above the template <> is referred to the class not to the method :

template <typename T>

class BlockCompressedMatrix :
                              public SparseMatrix<T>
{


   public: 


      virtual T& operator()(const std::size_t , const std::size_t) noexcept override = 0 ;

      virtual const T& operator()(const std::size_t , const std::size_t) const noexcept override = 0 ;

      virtual void print() const noexcept override = 0;


   protected:

     virtual std::size_t findBlockIndex(const std::size_t, const std::size_t ) const noexcept = 0 ;

     virtual T findValue(const std::size_t , const std::size_t ) const noexcept = 0;



};

and the derived is something like this ! (this compile)

# include "BlockCompressedMatrix.H"

namespace mg {
               namespace numeric {
                                    namespace algebra {

template <typename T>
class Block 
            : public BlockCompressedMatrix<T>

{
      public:

        Block(const std::size_t n) 
        {
            ba_.resize(n);
        }


        T& operator()(const std::size_t , const std::size_t ) noexcept override ;
        const T& operator()(const std::size_t , const std::size_t )const  noexcept override ;
        void constexpr print() const noexcept override ;    

      private:

      using SparseMatrix<T>::dummy ;
      std::vector<T> ba_ ;

      std::size_t findBlockIndex(const std::size_t , const std::size_t ) const noexcept override {return 0;} ;
      T findValue(const std::size_t , const std::size_t ) const noexcept override {return T(0);} ;



};

template <typename T>     
T& Block<T>::operator()(const std::size_t i, const std::size_t j) noexcept {
      dummy = ba_[0];
      return dummy ;
}

template <typename T>     
const T& Block<T>::operator()(const std::size_t i, const std::size_t j)const  noexcept {
      dummy = ba_[0];
      return dummy ;
}

template <typename T>
void constexpr Block<T>::print() const noexcept 
{
     std::cout << "Hello !" << std::endl; 

}
Drudox lebowsky
  • 1,020
  • 7
  • 21
  • 9
    You can't have a templated virtual function. You misrepresent something. – StoryTeller - Unslander Monica Dec 05 '17 at 08:41
  • More information https://stackoverflow.com/questions/2354210/can-a-c-class-member-function-template-be-virtual – Innokentiy Alaytsev Dec 05 '17 at 08:42
  • the `template` is referred to the class ! sorry I didn't explain in the post ! – Drudox lebowsky Dec 05 '17 at 08:48
  • done ! sorry for the wrong explanation at the beginning – Drudox lebowsky Dec 05 '17 at 08:51
  • 3
    I would say your problem is caused by design fault in the class hierarchy or interface. Solving your literal question, if solvable, does not solve the actual problem. –  Dec 05 '17 at 08:53
  • Now I guess the most crucial question - why don't you like it? :) – W.F. Dec 05 '17 at 08:55
  • I don't know ! doesn't looks a hierarchy problem ? if for you looks reasonable I'm happy about ! I thought that there was a specified way .. I have this problem only in one class .. all the other (almost 10 class) have this method with the same signature ! and so the abstract class looks good for these ! – Drudox lebowsky Dec 05 '17 at 08:59
  • 4
    You are violating the base class contract. If the base class specifies that there's a virtual function with some signature, derived classes **must** leave it alone or provide a **working** override. If your derived class doesn't need this function, then either the base class doesn't need it too, or it should't be a public base class of your derived class. You most probably need to rethink your hierarchy. Why in the world a block would be a subclass of a matrix? – n. m. could be an AI Dec 05 '17 at 09:01
  • because Block is a class written just to explain the problem .. the real class is BlockCompressedRowMatrix that **is an** matrix ! **is a** SparseMatrix , and **is a** BlockCompressed , this particular class need two more parameter for find the value (`findValue`) of the original sparse matrix without compressed storage – Drudox lebowsky Dec 05 '17 at 09:07
  • 4
    @Drudox - When you define an interface, you say "**all** derived classes work this way". And now you say "except this one". That's a contradiction! So either the base class is not defined correctly, or this derived class shouldn't be derived from that base. – Bo Persson Dec 05 '17 at 09:16
  • you're right , I have to find another way to write my findValue method to fit the hierarchy ! – Drudox lebowsky Dec 05 '17 at 09:52

0 Answers0