使用 Friend 运算符在模板 类 中重载运算符
Overloading Operators in Templates Classes with Friend Operators
考虑下面的 class Operand
:这是一个非常简单的 class 因为它接受一个参数并定义一堆重载运算符并且为了简单测试它class 我选择使用 float
类型,因为有除法运算符。如果您注意到某些运算符,它们被定义为朋友,因此可以在它们的代码中执行此操作:
编辑
有人在评论里问什么
inline friend Operand Operand::operator+( const Operand& A, const Operand B )
是什么意思?它是一个重载运算符,但由于已经为 class 本身定义了一个成员,因此它被声明为 class 的友元并在 class 中定义,但不是 class会员。这允许用户将两个 Operand class 实例或对象加在一起,并 returns 返回新计算的值作为 Operand 对象。我将在 snippet
部分添加关于正在使用的重载运算符的评论。
片段
Operand A( 2.3f );
Operand B( 4.5f );
Operand C( 0 );
Operand D( 0 );
C = A + B; // inline friend Operand Operand::operator+( const Operand& A, const Operand B );
D = C + 2.5f; // Overloaded Operator Defined as Class Member
D = 3.4f + B; // inline friend Operand Operand::operator+( const Value& value, const Operand A );
我用 4 个常见算术运算 +-*/
完成了此操作,其中一个运算符在 class 中定义为成员,并且为 4 个运算中的每一个定义了 2 个友元运算符。这是 class 定义。
Operand.h
#ifndef OPERAND_H
#define OPERAND_H
class Operand {
public:
static const float ZERO;
protected:
float operand_;
public:
explicit Operand( float a = float() ) : operand_( a ) {}
inline float getOperand() const {
return operand_;
}
inline Operand& operator+=( const float& value ) {
operand_ += value;
return *this;
}
inline Operand& operator-=( const float& value ) {
operand_ -= value;
return *this;
}
inline Operand& operator*=( const float& value ) {
operand_ *= value;
return *this;
}
inline Operand& operator/=( const float& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
}
inline Operand operator+() const { // Unary
return *this;
}
inline Operand operator+( const float& value ) const {
return Operand( operand_ + value );
}
inline Operand operator-() const { // Unary
return Operand( -operand_ );
}
inline Operand operator-( const float& value ) const {
return Operand( operand_ - value );
}
inline Operand operator*( const float& value ) const {
return Operand( operand_ * value );
}
inline Operand operator/( const float& value ) const {
if ( isZero( value ) ) {
return Operand( 0 );
} else {
return Operand( operand_ / value );
}
}
inline friend Operand Operand::operator+( const Operand& A, const Operand B ) {
return Operand( A.getOperand() + B.getOperand() );
}
inline friend Operand Operand::operator+( const float& value, Operand A ) {
return Operand( value + A.getOperand() );
}
inline friend Operand Operand::operator-( const Operand& A, const Operand B ) {
return Operand( A.getOperand() - B.getOperand() );
}
inline friend Operand Operand::operator-( const float& value, Operand A ) {
return Operand( value - A.getOperand() );
}
inline friend Operand Operand::operator*( const Operand& A, const Operand B ) {
return Operand( A.getOperand() * B.getOperand() );
}
inline friend Operand Operand::operator*( const float& value, const Operand A ) {
return Operand( value * A.getOperand() );
}
inline friend Operand Operand::operator/( const Operand& A, const Operand B ) {
if ( isZero( B.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( A.getOperand() / B.getOperand() );
}
}
inline friend Operand Operand::operator/( const float& value, const Operand A ) {
if ( isZero( A.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( value / A.getOperand() );
}
}
inline static bool isZero( float value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
} // isZero
}; // Operand
// #include "Operand.inl"
#endif // OPERAND_H
Operand.cpp
#include "Operand.h"
const float Operand::ZERO = static_cast<float>(1e-7);
我想做的是模板化这个class。
所以这里是相同的 class 仅定义为 class 模板:
OperandT.h
#ifndef OPERAND_T_H
#define OPERAND_T_H
template <typename T>
class OperandT {
public:
static const T ZERO;
protected:
T operand_;
public:
explicit OperandT<T>( T a = T() ) : operand_( a ) {}
inline T getOperand() const {
return operand_;
} // getOperand
inline OperandT<T>& operator+=( const T& value ) {
operand_ += value;
return *this;
} // operator+=
inline OperandT<T>& operator-=( const T& value ) {
operand_ -= value;
return *this;
} // operator-=
inline OperandT<T>& operator*=( const T& value ) {
operand_ *= value;
return *this;
} // operator*=
inline OperandT<T>& operator/=( const T& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
} // operator/=
inline OperandT<T> operator+() const {
return *this;
} // operator+ Unary
inline OperandT<T> operator+( const T& value ) const {
return OperandT<T>( operand_ + value );
} // operator+ Binary
inline OperandT<T> operator-() const {
return OperandT<T>( -operand_ );
} // operator- Unary (Negate Value)
inline OperandT<T> operator-( const T& value ) const {
return OperandT<T>( operand_ - value );
} // opeator- Binary (Subtraction)
inline OperandT<T> operator*( const T& value ) const {
return OperandT<T>( operand_ * value );
} // operator* Post Multiply
inline OperandT<T> operator/( const T& value ) const {
if ( isZero( value ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( operand_ / value );
}
} // operator/ Post Divide
/*/ Having Trouble With Operators When Using Templates and Friends
inline friend OperandT<T> OperandT<T>::operator+( const OperandT<T>& A, const OperandT<T> B ) {
return OperandT<T>( A.getOperand() + B.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator+( const float& value, OperandT<T> A ) {
return OperandT<T>( value + A.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator-( const OperandT<T>& A, const OperandT<T> B ) {
return OperandT<T>( A.getOperand() - B.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator-( const float& value, OperandT<T> A ) {
return OperandT<T>( value - A.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator*( const OperandT<T>& A, const OperandT<T> B ) {
return OperandT<T>( A.getOperand() * B.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator*( const float& value, const OperandT<T> A ) {
return OperandT<T>( value * A.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator/( const OperandT<T>& A, const OperandT<T> B ) {
if ( isZero( B.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( A.getOperand() / B.getOperand() );
}
}
inline friend OperandT<T> OperandT<T>::operator/( const float& value, const OperandT<T> A ) {
if ( isZero( A.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( value / A.getOperand() );
}
} */
inline static bool isZero( T value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
} // isZero
}; // OperandT
#include "OperandT.inl"
#endif // OPERAND_T_H
OperandT.cpp
#include "OperandT.h"
template <typename T>
const T OperandT<T>::ZERO = static_cast<T>( static_cast<float>(1e-7) );
如果友商运算符被注释掉,它可以编译,并且在 class 中定义的运算符可以工作,但是当我取消注释 class 的下半部分时,我最终会遇到编译器错误。
我的几个问题是:
- 是否有使用 class 模板定义友元运算符或函数的有效方法?
- 如果是这样,由于模板的奇怪,合适的语法是什么?
- 如果不是,有哪些可能的替代方案来实现相同的功能以使其尽可能通用?
- 最后,为什么朋友们在第一个class中工作得很好,但是一旦添加了模板的概念,您就完蛋了?
在评论区与 Danh
进行了简短的交谈后,他引起了我的注意,我能够在 visual studio 2013 - 15
中实现 overloaded friend operators
的方式应该被认为是一种漏洞。是的,它将在 visual studio 上编译 运行 并且在 visual studio 编译器 rextesters.com 上没有错误。他指出实现重载友元运算符的正确方法是这样的:
The proper way is friend Operand operator+(Operand A, Operand B)
or friend Operand operator+(const Operand& A, const Operand& B)
, I'm going to file a bug to MSFT – Danh
他还从这里向我展示了在 GCC 或 Clang 下编译失败的地方:http://melpon.org
我告诉他我会考虑到这一点,我做到了。所以我相应地更新了我的 Operand
header 文件,它正确地编译、构建和 运行s。
然后我继续修复模板版本,它也能正常工作。
这是更新后的 class headers.
Operand.h
#ifndef OPERAND_H
#define OPERAND_H
class Operand {
public:
static const float ZERO;
protected:
float operand_;
public:
explicit Operand( float a = float() ) : operand_( a ) {}
inline float getOperand() const {
return operand_;
}
inline Operand& operator+=( const float& value ) {
operand_ += value;
return *this;
}
inline Operand& operator-=( const float& value ) {
operand_ -= value;
return *this;
}
inline Operand& operator*=( const float& value ) {
operand_ *= value;
return *this;
}
inline Operand& operator/=( const float& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
}
inline Operand operator+() const { // Unary
return *this;
}
inline Operand operator+( const float& value ) const {
return Operand( operand_ + value );
}
inline Operand operator-() const { // Unary
return Operand( -operand_ );
}
inline Operand operator-( const float& value ) const {
return Operand( operand_ - value );
}
inline Operand operator*( const float& value ) const {
return Operand( operand_ * value );
}
inline Operand operator/( const float& value ) const {
if ( isZero( value ) ) {
return Operand( 0 );
} else {
return Operand( operand_ / value );
}
}
inline friend Operand operator+( const Operand& A, const Operand& B ) {
return Operand( A.getOperand() + B.getOperand() );
}
inline friend Operand operator+( const float& value, const Operand& A ) {
return Operand( value + A.getOperand() );
}
inline friend Operand operator-( const Operand& A, const Operand& B ) {
return Operand( A.getOperand() - B.getOperand() );
}
inline friend Operand operator-( const float& value, const Operand& A ) {
return Operand( value - A.getOperand() );
}
inline friend Operand operator*( const Operand& A, const Operand& B ) {
return Operand( A.getOperand() * B.getOperand() );
}
inline friend Operand operator*( const float& value, const Operand& A ) {
return Operand( value * A.getOperand() );
}
inline friend Operand operator/( const Operand& A, const Operand& B ) {
if ( isZero( B.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( A.getOperand() / B.getOperand() );
}
}
inline friend Operand operator/( const float& value, const Operand& A ) {
if ( isZero( A.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( value / A.getOperand() );
}
}
inline static bool isZero( float value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
}
}; // Operand
//#include "Operand.inl"
#endif // OPERAND_H
OperandT.h
#ifndef OPERAND_T_H
#define OPERAND_T_H
template <typename T>
class OperandT {
public:
static const T ZERO;
protected:
T operand_;
public:
explicit OperandT<T>( T a = T() ) : operand_( a ) {}
inline T getOperand() const {
return operand_;
}
inline OperandT<T>& operator+=( const T& value ) {
operand_ += value;
return *this;
}
inline OperandT<T>& operator-=( const T& value ) {
operand_ -= value;
return *this;
}
inline OperandT<T>& operator*=( const T& value ) {
operand_ *= value;
return *this;
}
inline OperandT<T>& operator/=( const T& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
}
inline OperandT<T> operator+() const {
return *this;
}
inline OperandT<T> operator+( const T& value ) const {
return OperandT<T>( operand_ + value );
}
inline OperandT<T> operator-() const {
return OperandT<T>( -operand_ );
}
inline OperandT<T> operator-( const T& value ) const {
return OperandT<T>( operand_ - value );
}
inline OperandT<T> operator*( const T& value ) const {
return OperandT<T>( operand_ * value );
}
inline OperandT<T> operator/( const T& value ) const {
if ( isZero( value ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( operand_ / value );
}
}
inline friend OperandT<T> operator+( const OperandT<T>& A, const OperandT<T>& B ) {
return OperandT<T>( A.getOperand() + B.getOperand() );
}
inline friend OperandT<T> operator+( const float& value, const OperandT<T>& A ) {
return OperandT<T>( value + A.getOperand() );
}
inline friend OperandT<T> operator-( const OperandT<T>& A, const OperandT<T>& B ) {
return OperandT<T>( A.getOperand() - B.getOperand() );
}
inline friend OperandT<T> operator-( const float& value, const OperandT<T>& A ) {
return OperandT<T>( value - A.getOperand() );
}
inline friend OperandT<T> operator*( const OperandT<T>& A, const OperandT<T>& B ) {
return OperandT<T>( A.getOperand() * B.getOperand() );
}
inline friend OperandT<T> operator*( const float& value, const OperandT<T>& A ) {
return OperandT<T>( value * A.getOperand() );
}
inline friend OperandT<T> operator/( const OperandT<T>& A, const OperandT<T>& B ) {
if ( isZero( B.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( A.getOperand() / B.getOperand() );
}
}
inline friend OperandT<T> operator/( const float& value, const OperandT<T>& A ) {
if ( isZero( A.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( value / A.getOperand() );
}
}
inline static bool isZero( T value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
}
}; // OperandT
//#include "OperandT.inl"
#endif // OPERAND_T_H
感谢 Danh
!
现在我的代码可以使用模板正常工作了
考虑下面的 class Operand
:这是一个非常简单的 class 因为它接受一个参数并定义一堆重载运算符并且为了简单测试它class 我选择使用 float
类型,因为有除法运算符。如果您注意到某些运算符,它们被定义为朋友,因此可以在它们的代码中执行此操作:
编辑 有人在评论里问什么
inline friend Operand Operand::operator+( const Operand& A, const Operand B )
是什么意思?它是一个重载运算符,但由于已经为 class 本身定义了一个成员,因此它被声明为 class 的友元并在 class 中定义,但不是 class会员。这允许用户将两个 Operand class 实例或对象加在一起,并 returns 返回新计算的值作为 Operand 对象。我将在 snippet
部分添加关于正在使用的重载运算符的评论。
片段
Operand A( 2.3f );
Operand B( 4.5f );
Operand C( 0 );
Operand D( 0 );
C = A + B; // inline friend Operand Operand::operator+( const Operand& A, const Operand B );
D = C + 2.5f; // Overloaded Operator Defined as Class Member
D = 3.4f + B; // inline friend Operand Operand::operator+( const Value& value, const Operand A );
我用 4 个常见算术运算 +-*/
完成了此操作,其中一个运算符在 class 中定义为成员,并且为 4 个运算中的每一个定义了 2 个友元运算符。这是 class 定义。
Operand.h
#ifndef OPERAND_H
#define OPERAND_H
class Operand {
public:
static const float ZERO;
protected:
float operand_;
public:
explicit Operand( float a = float() ) : operand_( a ) {}
inline float getOperand() const {
return operand_;
}
inline Operand& operator+=( const float& value ) {
operand_ += value;
return *this;
}
inline Operand& operator-=( const float& value ) {
operand_ -= value;
return *this;
}
inline Operand& operator*=( const float& value ) {
operand_ *= value;
return *this;
}
inline Operand& operator/=( const float& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
}
inline Operand operator+() const { // Unary
return *this;
}
inline Operand operator+( const float& value ) const {
return Operand( operand_ + value );
}
inline Operand operator-() const { // Unary
return Operand( -operand_ );
}
inline Operand operator-( const float& value ) const {
return Operand( operand_ - value );
}
inline Operand operator*( const float& value ) const {
return Operand( operand_ * value );
}
inline Operand operator/( const float& value ) const {
if ( isZero( value ) ) {
return Operand( 0 );
} else {
return Operand( operand_ / value );
}
}
inline friend Operand Operand::operator+( const Operand& A, const Operand B ) {
return Operand( A.getOperand() + B.getOperand() );
}
inline friend Operand Operand::operator+( const float& value, Operand A ) {
return Operand( value + A.getOperand() );
}
inline friend Operand Operand::operator-( const Operand& A, const Operand B ) {
return Operand( A.getOperand() - B.getOperand() );
}
inline friend Operand Operand::operator-( const float& value, Operand A ) {
return Operand( value - A.getOperand() );
}
inline friend Operand Operand::operator*( const Operand& A, const Operand B ) {
return Operand( A.getOperand() * B.getOperand() );
}
inline friend Operand Operand::operator*( const float& value, const Operand A ) {
return Operand( value * A.getOperand() );
}
inline friend Operand Operand::operator/( const Operand& A, const Operand B ) {
if ( isZero( B.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( A.getOperand() / B.getOperand() );
}
}
inline friend Operand Operand::operator/( const float& value, const Operand A ) {
if ( isZero( A.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( value / A.getOperand() );
}
}
inline static bool isZero( float value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
} // isZero
}; // Operand
// #include "Operand.inl"
#endif // OPERAND_H
Operand.cpp
#include "Operand.h"
const float Operand::ZERO = static_cast<float>(1e-7);
我想做的是模板化这个class。
所以这里是相同的 class 仅定义为 class 模板:
OperandT.h
#ifndef OPERAND_T_H
#define OPERAND_T_H
template <typename T>
class OperandT {
public:
static const T ZERO;
protected:
T operand_;
public:
explicit OperandT<T>( T a = T() ) : operand_( a ) {}
inline T getOperand() const {
return operand_;
} // getOperand
inline OperandT<T>& operator+=( const T& value ) {
operand_ += value;
return *this;
} // operator+=
inline OperandT<T>& operator-=( const T& value ) {
operand_ -= value;
return *this;
} // operator-=
inline OperandT<T>& operator*=( const T& value ) {
operand_ *= value;
return *this;
} // operator*=
inline OperandT<T>& operator/=( const T& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
} // operator/=
inline OperandT<T> operator+() const {
return *this;
} // operator+ Unary
inline OperandT<T> operator+( const T& value ) const {
return OperandT<T>( operand_ + value );
} // operator+ Binary
inline OperandT<T> operator-() const {
return OperandT<T>( -operand_ );
} // operator- Unary (Negate Value)
inline OperandT<T> operator-( const T& value ) const {
return OperandT<T>( operand_ - value );
} // opeator- Binary (Subtraction)
inline OperandT<T> operator*( const T& value ) const {
return OperandT<T>( operand_ * value );
} // operator* Post Multiply
inline OperandT<T> operator/( const T& value ) const {
if ( isZero( value ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( operand_ / value );
}
} // operator/ Post Divide
/*/ Having Trouble With Operators When Using Templates and Friends
inline friend OperandT<T> OperandT<T>::operator+( const OperandT<T>& A, const OperandT<T> B ) {
return OperandT<T>( A.getOperand() + B.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator+( const float& value, OperandT<T> A ) {
return OperandT<T>( value + A.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator-( const OperandT<T>& A, const OperandT<T> B ) {
return OperandT<T>( A.getOperand() - B.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator-( const float& value, OperandT<T> A ) {
return OperandT<T>( value - A.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator*( const OperandT<T>& A, const OperandT<T> B ) {
return OperandT<T>( A.getOperand() * B.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator*( const float& value, const OperandT<T> A ) {
return OperandT<T>( value * A.getOperand() );
}
inline friend OperandT<T> OperandT<T>::operator/( const OperandT<T>& A, const OperandT<T> B ) {
if ( isZero( B.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( A.getOperand() / B.getOperand() );
}
}
inline friend OperandT<T> OperandT<T>::operator/( const float& value, const OperandT<T> A ) {
if ( isZero( A.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( value / A.getOperand() );
}
} */
inline static bool isZero( T value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
} // isZero
}; // OperandT
#include "OperandT.inl"
#endif // OPERAND_T_H
OperandT.cpp
#include "OperandT.h"
template <typename T>
const T OperandT<T>::ZERO = static_cast<T>( static_cast<float>(1e-7) );
如果友商运算符被注释掉,它可以编译,并且在 class 中定义的运算符可以工作,但是当我取消注释 class 的下半部分时,我最终会遇到编译器错误。
我的几个问题是:
- 是否有使用 class 模板定义友元运算符或函数的有效方法?
- 如果是这样,由于模板的奇怪,合适的语法是什么?
- 如果不是,有哪些可能的替代方案来实现相同的功能以使其尽可能通用?
- 最后,为什么朋友们在第一个class中工作得很好,但是一旦添加了模板的概念,您就完蛋了?
在评论区与 Danh
进行了简短的交谈后,他引起了我的注意,我能够在 visual studio 2013 - 15
中实现 overloaded friend operators
的方式应该被认为是一种漏洞。是的,它将在 visual studio 上编译 运行 并且在 visual studio 编译器 rextesters.com 上没有错误。他指出实现重载友元运算符的正确方法是这样的:
The proper way is
friend Operand operator+(Operand A, Operand B)
orfriend Operand operator+(const Operand& A, const Operand& B)
, I'm going to file a bug to MSFT – Danh
他还从这里向我展示了在 GCC 或 Clang 下编译失败的地方:http://melpon.org
我告诉他我会考虑到这一点,我做到了。所以我相应地更新了我的 Operand
header 文件,它正确地编译、构建和 运行s。
然后我继续修复模板版本,它也能正常工作。
这是更新后的 class headers.
Operand.h
#ifndef OPERAND_H
#define OPERAND_H
class Operand {
public:
static const float ZERO;
protected:
float operand_;
public:
explicit Operand( float a = float() ) : operand_( a ) {}
inline float getOperand() const {
return operand_;
}
inline Operand& operator+=( const float& value ) {
operand_ += value;
return *this;
}
inline Operand& operator-=( const float& value ) {
operand_ -= value;
return *this;
}
inline Operand& operator*=( const float& value ) {
operand_ *= value;
return *this;
}
inline Operand& operator/=( const float& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
}
inline Operand operator+() const { // Unary
return *this;
}
inline Operand operator+( const float& value ) const {
return Operand( operand_ + value );
}
inline Operand operator-() const { // Unary
return Operand( -operand_ );
}
inline Operand operator-( const float& value ) const {
return Operand( operand_ - value );
}
inline Operand operator*( const float& value ) const {
return Operand( operand_ * value );
}
inline Operand operator/( const float& value ) const {
if ( isZero( value ) ) {
return Operand( 0 );
} else {
return Operand( operand_ / value );
}
}
inline friend Operand operator+( const Operand& A, const Operand& B ) {
return Operand( A.getOperand() + B.getOperand() );
}
inline friend Operand operator+( const float& value, const Operand& A ) {
return Operand( value + A.getOperand() );
}
inline friend Operand operator-( const Operand& A, const Operand& B ) {
return Operand( A.getOperand() - B.getOperand() );
}
inline friend Operand operator-( const float& value, const Operand& A ) {
return Operand( value - A.getOperand() );
}
inline friend Operand operator*( const Operand& A, const Operand& B ) {
return Operand( A.getOperand() * B.getOperand() );
}
inline friend Operand operator*( const float& value, const Operand& A ) {
return Operand( value * A.getOperand() );
}
inline friend Operand operator/( const Operand& A, const Operand& B ) {
if ( isZero( B.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( A.getOperand() / B.getOperand() );
}
}
inline friend Operand operator/( const float& value, const Operand& A ) {
if ( isZero( A.getOperand() ) ) {
return Operand( 0 );
} else {
return Operand( value / A.getOperand() );
}
}
inline static bool isZero( float value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
}
}; // Operand
//#include "Operand.inl"
#endif // OPERAND_H
OperandT.h
#ifndef OPERAND_T_H
#define OPERAND_T_H
template <typename T>
class OperandT {
public:
static const T ZERO;
protected:
T operand_;
public:
explicit OperandT<T>( T a = T() ) : operand_( a ) {}
inline T getOperand() const {
return operand_;
}
inline OperandT<T>& operator+=( const T& value ) {
operand_ += value;
return *this;
}
inline OperandT<T>& operator-=( const T& value ) {
operand_ -= value;
return *this;
}
inline OperandT<T>& operator*=( const T& value ) {
operand_ *= value;
return *this;
}
inline OperandT<T>& operator/=( const T& value ) {
if ( isZero( value ) ) {
operand_ = 0;
} else {
operand_ /= value;
}
}
inline OperandT<T> operator+() const {
return *this;
}
inline OperandT<T> operator+( const T& value ) const {
return OperandT<T>( operand_ + value );
}
inline OperandT<T> operator-() const {
return OperandT<T>( -operand_ );
}
inline OperandT<T> operator-( const T& value ) const {
return OperandT<T>( operand_ - value );
}
inline OperandT<T> operator*( const T& value ) const {
return OperandT<T>( operand_ * value );
}
inline OperandT<T> operator/( const T& value ) const {
if ( isZero( value ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( operand_ / value );
}
}
inline friend OperandT<T> operator+( const OperandT<T>& A, const OperandT<T>& B ) {
return OperandT<T>( A.getOperand() + B.getOperand() );
}
inline friend OperandT<T> operator+( const float& value, const OperandT<T>& A ) {
return OperandT<T>( value + A.getOperand() );
}
inline friend OperandT<T> operator-( const OperandT<T>& A, const OperandT<T>& B ) {
return OperandT<T>( A.getOperand() - B.getOperand() );
}
inline friend OperandT<T> operator-( const float& value, const OperandT<T>& A ) {
return OperandT<T>( value - A.getOperand() );
}
inline friend OperandT<T> operator*( const OperandT<T>& A, const OperandT<T>& B ) {
return OperandT<T>( A.getOperand() * B.getOperand() );
}
inline friend OperandT<T> operator*( const float& value, const OperandT<T>& A ) {
return OperandT<T>( value * A.getOperand() );
}
inline friend OperandT<T> operator/( const OperandT<T>& A, const OperandT<T>& B ) {
if ( isZero( B.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( A.getOperand() / B.getOperand() );
}
}
inline friend OperandT<T> operator/( const float& value, const OperandT<T>& A ) {
if ( isZero( A.getOperand() ) ) {
return OperandT<T>( 0 );
} else {
return OperandT<T>( value / A.getOperand() );
}
}
inline static bool isZero( T value ) {
if ( (value > -ZERO) && (value < ZERO) ) {
return true;
}
return false;
}
}; // OperandT
//#include "OperandT.inl"
#endif // OPERAND_T_H
感谢 Danh
!