Richard Keil
Richard Keil

Reputation: 23

Does overriding a function instantiate the base function? (getting error)

I would like to write a converter. I would prefer a base class that already handles the trivial cases where InputType can be directly converter to OutputType, say float to double.

However, in this shortened example, I get an error:

error C2440: 'static_cast' : cannot convert from 'const Eigen::Vector2d' to 'std::tuple<double,double>'

To me that looks like, the base class and set function are instantiated, despite the function being overridden. Since there is no conversion between Eigen::Vector2d and std::tuple the error appears. Am I missing something? What would be a proper way to achieve the initial goal?

The base class which is supposed to also handle trivial cases like OutputType = InputType:

template <typename InputType, typename OutputType>
class DefaultConverter 
{
public:
    virtual void set(const InputType& input)
    {
        output = static_cast<OutputType>(input);
    }
protected:
    OutputType output;
};

Now the derived class that causes the error:

class Array2Eigen : public DefaultConverter<Eigen::Vector2d, std::tuple<double, double>>
{
public:
    void set(const Eigen::Vector2d& input) override
    {
        output = std::make_tuple(input[0], input[1]);
    }
    double getFirst() { return std::get<0>(output); }
};

Some code for testing:

int main(int argc, _TCHAR* argv[])
{
    Eigen::Vector2d input(1.0, 2.0);
    Array2Eigen converter;
    converter.set(input);

    std::cout << converter.getFirst() << std::endl;
    return 0;
}

Upvotes: 1

Views: 44

Answers (1)

Jarod42
Jarod42

Reputation: 217085

Virtual methods are instantiated in the same time than the class, so it should be correct.

You might provide 2 versions:

template <typename InputType, typename OutputType, typename Enabler = void>
class DefaultConverter 
{
public:
    virtual ~DefaultConverter() = default;
    virtual void set(const InputType& input) = 0;

protected:
    OutputType output;
};

template <typename InputType, typename OutputType>
class DefaultConverter<InputType, OutputType,
                       std::enable_if_t<std::is_convertible_v<InputType, OutputType>>>
{
public:
    virtual ~DefaultConverter() = default;
    virtual void set(const InputType& input)
    {
        output = static_cast<OutputType>(input);
    }

protected:
    OutputType output;
};

Upvotes: 1

Related Questions