数值的包装器

Wrapper for numeric values

本文关键字:包装      更新时间:2023-10-16

我正在尝试编写一个包装数值的C++程序,我正在通过编写一个处理两个简单函数的超类和一个运算符重载函数来做到这一点。这是我到目前为止的代码:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

template <class T>
class Number {
protected:
    T number;
public:
    Number(T num) {
        number = num;
    }
    string mytype() {
        return typeid(number).name();
    }
    string what_am_i() {
        ostringstream oss;
        oss << "I am " << Number<T>::mytype() << " and my value is " << number;
        return oss.str();
    }
    Number operator+ (Number an) {
        Number brandNew = NULL;
        brandNew.number = number + an.number;
        return brandNew;
    }
};

class MyInt : public Number<int> {
public:
    MyInt() : Number<int>(0) {};
    MyInt(int num) : Number<int>(num) {}
    MyInt(const Number<int> &x) : Number<int>(x) {}
};

class MyFloat : public Number<float> {
public:
    MyFloat() : Number<float>(0){};
    MyFloat(float num) : Number(num){}
    MyFloat(const Number<float> &x) : Number<float>(x) {}   
};
class MyDouble : public Number<double> {
public:
    MyDouble() : Number<double>(0){};
    MyDouble(double num) : Number(num){}
    MyDouble(const Number<double> &x) : Number<double>(x) {}    
};

在主函数中,我想做这样的事情:

void main() {       
    MyInt two = 2;       
    MyFloat flo = 5.0f;
    MyDouble md3 = flo + two;
}

并希望 md3 为 15.00000,到目前为止,添加来自同一类型的两个对象效果很好,但是当我尝试添加 MyInt 和 MyFloat 时,编译器不喜欢它。有没有人知道我该如何实现这一点?

您必须为模板类添加类型运算符:

operator T()
{
    return number;
}

这是我测试和工作的 complate 代码:

template <class T>
class Number {
protected:
    T number;
public:
    Number(T num) {
        number = num;
    }
    string mytype() {
        return typeid(number).name();
    }
    string what_am_i() {
        ostringstream oss;
        oss << "I am " << Number<T>::mytype() << " and my value is " << number;
        return oss.str();
    }
    Number operator+ (Number an) {
        Number brandNew = NULL;
        brandNew.number = number + an.number;
        return brandNew;
    }
    operator T()
    {
        return number;
    }
};

我试图更好地解释它为什么有效。当您重载 plus 运算符时,您需要执行以下操作:left_value + right_value ,其中 right_value 是 plus 运算符的 "an" 参数。

现在要获得对象"an"的正确值,您必须重载"类型运算符",如果您不在 Number 类中重载此运算符,则无法将其读取为正确的值。以下示例适用于运算符 =(),但也适用于运算符+():

template<typename T>
class Number
{
  T value;
  public:
  T operator=(T arg) // Assignment, your class is seen as left operand
  {
    value = arg;
  }
  operator T() // Getting, your class is seen as right operand
  {
     return value;
  } 
}
Number<int>     A;  // define a new class Number as int
Number<double>  B;  // define a new class Number as double
A = B; // is same to A.operator=( B.double() );
将 A 指定为左值称为类 Number 的运算符"operator=()"

,而将 B 作为右值称为类 Number 的"运算符 T()"

现在这被翻译为:

// instance of the operator = of the class Number<int>
int operator=(int arg)
{
}

// instance of the Operator T of the class Number<double>
operator double()
{
}

此遍历模拟 A 和 B 对象的以下语义:

int A;
double B;
A = B;

再见安杰洛

您可以指定二进制运算的结果并使用独立运算符:

#include <iostream>
#include <typeinfo>
template <class T>
class Number {
template <typename>
friend class Number;
protected:
    T number;
public:
    Number(const T& num)
    :   number(num)
    {}
    template <typename U>
    Number(const Number<U>& num)
    :   number(num.number)
    {}
    // ...
    const T& value() const { return number; }
};
typedef Number<int> MyInt;
typedef Number<float> MyFloat;
typedef Number<double> MyDouble;
template <typename A, typename B>
struct NumberResult;
template <typename X>
struct NumberResult<X, X> {
    typedef X type;
};
template <> struct NumberResult<int, float> { typedef float type; };
template <> struct NumberResult<float, int> { typedef float type; };
// ...
template <typename A, typename B>
inline Number<typename NumberResult<A, B>::type>
operator + (const Number<A>& a, const Number<B>& b) {
    return Number<typename NumberResult<A, B>::type>(a.value() + b.value());
}

注意:请避免在标题中using namespace std;