1

How do I ensure my derived class implements at least one of two chosen methods in the base class?

    class base {
     public:

     virtual int sample()=0;
     virtual Eigen::VectorXf sample()=0;
    };

    class Derived : Base {
    int sample() override {return 1;}

    }

This code returns an error, as the sample method is not implemented with the VectorXf return type. However, my intention is that only one of these need to be implemented. The only reason they are seperate in the base class is that they have different return type. How can I do this in C++?

Sridhar Thiagarajan
  • 580
  • 1
  • 7
  • 20

1 Answers1

2

Overloading by return type is not possible. You may use std::variant instead:

#include <variant>
class Base {
 public:

  virtual std::variant<int, Eigen::VectorXf> sample()=0;
};

class Derived : public Base {
  std::variant<int, Eigen::VectorXf> sample() override {return 1;}

};

If one is restricted to C++11, then there are many alternatives.

  1. Implement and use something like variant: a class that has a enumerator selecting between two active types, and a union to contain these types.
  2. Use Boost variant.
  3. std::pair
  4. Implement a hierarchy of classes (a simplification of std::any), and return on the right pointer to object:

    class AbstractBase {
       public:
           virtual ~AbstractBase() = 0;
           template <class T>
           const T* get() const;
    };
    template <class T>
    class ValueWrapper : public AbstractBase {
           public:
              ValueWrapper(const T& value) : m_value(value) {}
              const T & getValue() const { return m_value; }
           private:
              T m_value;
    };
    
    template <class T>              
    inline const T * AbstractBase::get() const {
        auto child = dynamic_cast<ValueWrapper<T> const*>(this);
        return child ? &child->getValue() : nullptr;
    }
    class Base {
      public:
        virtual std::unique_ptr<AbstractBase> sample()=0;
    };
    

The question is, why would you need this?

Michael Veksler
  • 8,217
  • 1
  • 20
  • 33
  • Is there a way to do this in C++ 11? – Sridhar Thiagarajan Jul 03 '19 at 07:07
  • @SridharThiagarajan [`boost::variant`](https://www.boost.org/doc/libs/1_70_0/doc/html/variant.html) or a `std::pair` of an `enum` to identify which member is active and a `union` of `int` and `Eigen::VectorXf` would probably be the most direct. – user4581301 Jul 03 '19 at 07:17
  • 1
    Thinking on this though, this has the smell of violating the [Liskov Substitution Principle](https://stackoverflow.com/questions/56860/what-is-an-example-of-the-liskov-substitution-principle), so take care. – user4581301 Jul 03 '19 at 07:21