5

フロートをより簡単に比較するために、小さなFloatクラスを作成しています(フロートの精度のために、私たちが知っているように)。したがって、 doubleが持つほとんどすべての演算子をリロードする必要があります。operator +operator-operator *operator/などの繰り返しが多すぎることがわかりました。それらは似ています。そこで、マクロを使用してコードの長さを短くしました。しかし、私がそれに従うと、それは機能しません。エラーは次のとおりです。

happy.cc:24:1: error: pasting "operator" and "+" does not give a valid preprocessing token
happy.cc:25:1: error: pasting "operator" and "-" does not give a valid preprocessing token
happy.cc:26:1: error: pasting "operator" and "*" does not give a valid preprocessing token
happy.cc:27:1: error: pasting "operator" and "/" does not give a valid preprocessing token

これが私のコードです:

struct Float
{
  typedef double size_type;
  static const size_type EPS = 1e-8;
private:
  size_type x;
public:
  Float(const size_type value = .0): x(value) { }
  Float& operator+=(const Float& rhs) { x += rhs.x; return *this; }
  Float& operator-=(const Float& rhs) { x -= rhs.x; return *this; }
  Float& operator*=(const Float& rhs) { x *= rhs.x; return *this; }
  Float& operator/=(const Float& rhs) { x /= rhs.x; return *this; }
};
#define ADD_ARITHMETIC_OPERATOR(x) \
inline const Float operator##x(const Float& lhs, const Float& rhs)\
{\
  Float result(lhs);\
  return result x##= rhs;\
}
ADD_ARITHMETIC_OPERATOR(+)
ADD_ARITHMETIC_OPERATOR(-)
ADD_ARITHMETIC_OPERATOR(*)
ADD_ARITHMETIC_OPERATOR(/)

そして私のg++バージョンは4.4.3です

これがg++-Eの結果です。

struct Float
{
  typedef double size_type;
  static const size_type EPS(1e-8);
private:
  size_type x;
public:
  Float(const size_type value = .0): x(value) { }
  Float& operator+=(const Float& rhs) { x += rhs.x; return *this; }
  Float& operator-=(const Float& rhs) { x -= rhs.x; return *this; }
  Float& operator*=(const Float& rhs) { x *= rhs.x; return *this; }
  Float& operator/=(const Float& rhs) { x /= rhs.x; return *this; }
};





inline const Float operator+(const Float& lhs, const Float& rhs){ Float result(lhs); return result += rhs;}
inline const Float operator-(const Float& lhs, const Float& rhs){ Float result(lhs); return result -= rhs;}
inline const Float operator*(const Float& lhs, const Float& rhs){ Float result(lhs); return result *= rhs;}
inline const Float operator/(const Float& lhs, const Float& rhs){ Float result(lhs); return result /= rhs;}
4

2 に答える 2

16

##トークンを連結して単一のトークンを生成します。結果は有効な単一トークンである必要があります。operatorたとえば、operator+実際には単一のトークンではないため、これを行う必要はありません。

#define ADD_ARITHMETIC_OPERATOR(x) \
inline const Float operator x(const Float& lhs, const Float& rhs)\
{\
  Float result(lhs);\
  return result x##= rhs;\
}

厳密に言えば、あなた後のトークンのために単一のトークンを作成しています。

GCCのような、トークン化中に動作するのではなく、実際にはテキストのプリプロセッサであるプリプロセッサは、多くの場合、これについて寛大です。

于 2012-04-14T03:49:56.930 に答える
3

##マクロでを使用することはできません。貼り付けられるトークンは識別子である必要があります。

マクロ内の2つのオカレンスのうち最初のオカレンスは、単にスペースに置き換えることができます。2番目ははるかに問題があります。表面的には、次のことでうまくいく可能性があります。

#define ADD_ARITHMETIC_OPERATOR(x) \
inline const Float operator x(const Float& lhs, const Float& rhs)\
{\
  Float result(lhs);\
  return result x= rhs;\
}

ただし、それは間違いなく定義された動作ではありません。とは別個の前処理トークンでありx=プリプロセッサによって単一のトークンに結合されることはありません(結合されるべきではありません)。私はあなたが使用する必要があると思います:

#define ADD_ARITHMETIC_OPERATOR(x, y) \
inline const Float operator x(const Float& lhs, const Float& rhs)\
{\
  Float result(lhs);\
  return result y rhs;\
}
ADD_ARITHMETIC_OPERATOR(+, +=)
于 2012-04-14T03:54:38.870 に答える