问题 定义一个像整数无穷大一样的对象


我已经创建了一个对象,对于长整数,它的行为有点像无穷大。特别:

#ifndef MU_INF_H
#define MU_INF_H
#include "mu.h"
namespace mu {
  class Inf {
  public:
    bool operator> ( long int i ) { return true; }
    bool operator> ( Inf i ) { return false; }
    ... lots of other boolean operators ...
    Inf& operator+ ( long int i ) { return *this; }
    Inf& operator+ ( Inf i ) { return *this; }
    ... lots of other integer operators ...
  };   // class Inf
}      // namespace mu
#endif

这一切都很好,允许我运行表单的单元测试:

  mu::Inf inf;
  long int n = -1;
  long int z = 0;
  long int p = 1;

  ASSERT((inf + inf) == inf);
  ASSERT((inf + n) == inf);
  ASSERT((inf + z) == inf);
  ASSERT((inf + p) == inf);

  ASSERT((inf > inf) == false);
  ASSERT((inf > n) == true);
  ASSERT((inf > z) == true);
  ASSERT((inf > p) == true);

冒着无法指定复选标记的风险,我有三个问题:

  • C ++是否已经提供了这样的东西,和/或是否有比我在这里做的明显更好的方式?
  • 我想在整个系统中创建一个Inf实例。我不能宣布它 static const 因为它不是一个“简单”的对象。什么是正确的方法:全球?单身模式?
  • 有没有办法处理long int首先出现的对称运算符,即 ASSERT((1 + inf) == inf)? (如果没有,我不会太伤心。)

3361
2018-05-05 05:14


起源

你什么意思 it's not a "simple" object? - Bryan Chen
如果您的代码有效,您可能会获得更好的codereview.stackexchange帮助,并且您希望获得更好的建议。 - ApproachingDarknessFish
@BryanChen:我的意思是我做不到 static const Inf kInfinity = new Inf() 或任何类似的东西使它成为一个静态常数。 - fearless_fool
要使对称运算符成为自由函数: Inf operator+(Inf a, inf b) { return a += b;} 。你现有的 operator+ 不遵循通常的语义 operator+ 可能会让人感到困惑(它会做什么 operator+= 通常会)。 - M.M
@fearless_fool static const Inf kInfinity; - M.M


答案:


static const Inf kInfinity; 工作,将使用默认构造函数。

operator+ 应该是一个按值返回的自由函数:

Inf operator+(Inf a, Inf b) { return a += b; }

您表示您希望返回引用 kInfinity 而不是一个值。这是可能的(尽管对我来说似乎有些笨拙);一个 const 因此,必须返回参考 kInfinity 是 const


5
2018-05-05 05:35



注意:静态const的初始化需要用户提供的默认构造函数。系统默认不会削减它。我只提到它,因为OP发布的课程确实如此 不 有一个。 (和+1顺便说一句)。 - WhozCraig


  1. 不是我知道的,虽然在我看来你使用的是引用 Inf 和重载中的实际对象以凌乱的方式。

    通常,您按值或参数进行参数 const 除了复合赋值(通过引用返回)之外的所有运算符的引用和返回值,以获得预期的语义。当然,由于你的Inf对象没有状态,所以这在某种程度上才有意义。

  2. 我用了一个 const 全局避免括号和单例中涉及的潜在函数调用。这是否也是 static 应该几乎没有差别(你没有访问 this 以任何方式)。

  3. 您必须将您的运算符编写为自由函数:

    inline Inf operator+(long int i, const Inf&) { return *this;} 
    

6
2018-05-05 05:26



+1。并注意OP可以覆盖一个 批量 比基础更多的基础 long如果使用SFINAE驱动的一组自由函数。很好的答案。 - WhozCraig


每个人都非常有助于指导我走向真正的道路。为了帮助那些寻找答案的人,而不是让你从整个线程中拼凑出答案,我想我会发布我最终的答案。当然,欢迎提出改进的评​​论。

#ifndef MU_INDEFINITE_H
#define MU_INDEFINITE_H

namespace mu {

  class Indefinite {
  public:

    static const Indefinite kIndefinite;

    Indefinite() {}
    ~Indefinite() {}

  };

  inline Indefinite operator+ (long int i, Indefinite t) { return Indefinite::kIndefinite; }
  inline Indefinite operator+ (Indefinite t, long int i) { return Indefinite::kIndefinite; }
  inline Indefinite operator+ (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; }

  inline Indefinite operator- (long int i, Indefinite t) { return Indefinite::kIndefinite; }
  inline Indefinite operator- (Indefinite t, long int i ) { return Indefinite::kIndefinite; }
  inline Indefinite operator- (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; }

  inline Indefinite operator* (long int i, Indefinite t) { return Indefinite::kIndefinite; }
  inline Indefinite operator* (Indefinite t, long int i ) { return Indefinite::kIndefinite; }
  inline Indefinite operator* (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; }

  // It's not clear what i / Indefinite should produce.  Forbid it for now.
  // inline long int operator/ (long int i, Indefinite t) { return 0; }
  inline Indefinite operator/ (Indefinite t, long int i ) { return Indefinite::kIndefinite; }
  inline Indefinite operator/ (Indefinite t1, Indefinite t2) { return Indefinite::kIndefinite; }

  inline bool operator> (long int i, Indefinite t) { return false; }
  inline bool operator> (Indefinite t, long int i) { return true; }
  inline bool operator> (Indefinite t1, Indefinite t2) { return false; }

  inline bool operator>= (long int i, Indefinite t) { return false; }
  inline bool operator>= (Indefinite t, long int i) { return true; }
  inline bool operator>= (Indefinite t1, Indefinite t2) { return true; }

  inline bool operator< (long int i, Indefinite t) { return true; }
  inline bool operator< (Indefinite t, long int i) { return false; }
  inline bool operator< (Indefinite t1, Indefinite t2) { return false; }

  inline bool operator<= (long int i, Indefinite t) { return true; }
  inline bool operator<= (Indefinite t, long int i) { return false; }
  inline bool operator<= (Indefinite t1, Indefinite t2) { return true; }

  inline bool operator== (long int i, Indefinite t) { return false; }
  inline bool operator== (Indefinite t, long int i) { return false; }
  inline bool operator== (Indefinite t1, Indefinite t2) { return true; }

  inline bool operator!= (long int i, Indefinite t) { return true; }
  inline bool operator!= (Indefinite t, long int i) { return true; }
  inline bool operator!= (Indefinite t1, Indefinite t2) { return false; }

}

#endif

0
2018-05-05 16:39