我正在编写一个类模板,该模板可以采用以下之一:int8_t,int16_t,int32_t,float和double。在这里:
#ifndef OPERAND_HPP
# define OPERAND_HPP
# include "IOperand.hpp"
# include <regex>
template <typename T>
class Operand : public IOperand {
private:
/* Constructors - Destructors */
Operand() = default;
/* Attributes */
T _num;
eOperandType const _type;
std::string const &_value;
/* Static functions */
static int8_t getValue(Operand<int8_t> const *it) { return it->getNum(); }
static int16_t getValue(Operand<int16_t> const *it) { return it->getNum(); }
static int32_t getValue(Operand<int32_t> const *it) { return it->getNum(); }
static float getValue(Operand<float> const *it) { return it->getNum(); }
static double getValue(Operand<double> const *it) { return it->getNum(); }
public:
/* Constructors - Destructors */
explicit Operand(eOperandType t, std::string const &v, T n) : _num(n), _type(t), _value(v) {}
Operand(Operand const &rhs) : Operand(rhs.getType(), rhs.toString(), rhs.getNum()) {};
~Operand() override = default;
/* Operator overloads */
Operand<T> &operator=(Operand const &rhs) {
_num = rhs.getNum();
_type = rhs.getType();
_value = rhs.toString();
return *this;
}
IOperand const *operator+(IOperand const &rhs) const final {
Operand::getValue(&rhs);
return &rhs;
}
IOperand const *operator-(IOperand const &rhs) const final { return &rhs; }
IOperand const *operator*(IOperand const &rhs) const final { return &rhs; }
IOperand const *operator/(IOperand const &rhs) const final { return &rhs; }
IOperand const *operator%(IOperand const &rhs) const final { return &rhs; }
/* ------------------------------------------------- Exceptions ------------------------------------------------- */
class DivisionByZero : public std::exception {
public:
char const *what() const noexcept final { return "division by zero"; }
};
class ModuloByZero : public std::exception {
public:
char const *what() const noexcept final { return "modulo by zero"; }
};
class Overflow : public std::exception {
public:
char const *what() const noexcept final { return "overflow"; }
};
class Underflow : public std::exception {
public:
char const *what() const noexcept final { return "underflow"; }
};
/* -------------------------------------------------------------------------------------------------------------- */
/* Member functions */
T getNum() const { return _num; }
int getPrecision() const final { return static_cast<int>(_type); }
eOperandType getType() const final { return _type; }
std::string const &toString() const final { return _value; }
};
#endif /* OPERAND_HPP */
该类从以下接口继承:
#ifndef IOPERAND_HPP
# define IOPERAND_HPP
# include <string>
enum eOperandType {
INT8,
INT16,
INT32,
FLOAT,
DOUBLE
};
class IOperand {
public:
/* Constructors - Destructors */
virtual ~IOperand() = default;
/* Operator overloads */
virtual IOperand const *operator+(IOperand const &) const = 0;
virtual IOperand const *operator-(IOperand const &) const = 0;
virtual IOperand const *operator*(IOperand const &) const = 0;
virtual IOperand const *operator/(IOperand const &) const = 0;
virtual IOperand const *operator%(IOperand const &) const = 0;
/* Member functions */
virtual int getPrecision() const = 0;
virtual eOperandType getType() const = 0;
virtual std::string const &toString() const = 0;
};
#endif /* IOPERAND_HPP */
我正在努力实现+运算符重载。该函数有两个IOperand&作为参数,但是我需要访问所述参数的_num属性。此属性的getter不在基类中,而仅在派生类中。我尝试使用以下功能进行多态:
static int8_t getValue(Operand<int8_t> const *it) { return it->getNum(); }
static int16_t getValue(Operand<int16_t> const *it) { return it->getNum(); }
static int32_t getValue(Operand<int32_t> const *it) { return it->getNum(); }
static float getValue(Operand<float> const *it) { return it->getNum(); }
static double getValue(Operand<double> const *it) { return it->getNum(); }
但是使用clang ++编译时出现以下错误消息:
./Operand.tpp:41:15: error: no matching function for call to 'getValue'
(void)Operand::getValue(&rhs);
./Operand.tpp:19:29: note: candidate function not viable: cannot convert from base class pointer 'const IOperand *' to derived class pointer 'const Operand<int8_t> *'
(aka 'const Operand<signed char> *') for 1st argument
static int8_t getValue(Operand<int8_t> const *it) { return it->getNum(); }
该错误消息非常冗长,我理解问题出在哪里。但是我不确定如何解决它,或者不确定是否有更优雅的方法来解决我的问题。我可能可以使用动态强制转换,甚至使用5个不同的类而不是模板来摆脱它,但这似乎并不好。
有人能指出我正确的方向吗?