首页 文章

C友比较一个类模板的两个实例

提问于
浏览
1

我正在尝试编写一个类模板,该模板在两个具有不同模板类型的实例之间提供比较运算符 . 通常情况下,该运营商是非会员朋友 . 我想要实现的一个简化示例如下所示 .

template<typename T>
class Wrapper {
  // Base type, which must have a val() method to allow comparison
  T t_;
public:
  Wrapper(const T& t) : t_(t) {}

  // Comparison operator
  template<typename B>
  friend
  bool
  operator==(const Wrapper &a, const Wrapper<B>&b) {
    return a.t_.val()==b.t_.val();
  }
};

// First example type for Wrapper
class X {
  int x_;    
public:
  X(int x) : x_(x) {}

  int
  val() const {return x_;}
};

// Second example type for Wrapper
class Y {
  int y_;
public:
  Y(int y) : y_(y) {}

  int
  val() const {return 2*y_;}
};

int
main() {
  Wrapper<X> WX(X(4));
  Wrapper<Y> WY(Y(2));
  return WX==WY ? 1 : 0;
}

这个例子(g 4.4.0)没有编译:相反它抱怨来自 Wrapper<Y>y_ 是私有的,因此朋友函数无法访问,我可以看到原因 . 但是我该如何解决这个问题呢?为反转功能添加友谊

template<typename B>
  friend bool operator==(const Wrapper<B> &, const Wrapper &);

进入Wrapper类模板体只会导致编译器的歧义 . 我不想允许Wrapper类的不同实例访问彼此的私有成员 - 我想限制对这一个操作符的访问 . 这可能吗?

我的笔记本电脑因为被解开而处于危险之中,因此我和笔记本电脑(以及相关的窗口)都会有任何想法 .

2 回答

  • 2

    我的笔记本电脑是安全的(现在)重新阅读C++ FAQ-lite结果是帮助,虽然这个例子最初似乎不符合我自己的问题 . 通过在模板类主体外部移动运算符的定义,以下工作:

    template <typename T> class Wrapper;
    
    template<typename A, typename B>
    inline
    bool
    operator==(const Wrapper<A> &a, const Wrapper<B>&b) {return a.t_.val()==b.t_.val();}
    
    template<typename T>
    class Wrapper {
      T t_;
    public:
      Wrapper(const T& t) : t_(t) {}
    
      template<typename A, typename B>
      friend
      bool
      operator==(const Wrapper<A> &a, const Wrapper<B>&b);
    };
    

    任何更优雅或富有洞察力的建议将不胜感激 .

  • 2

    事物数量:

    • 当您的类模板为 X 实例化一次而 Y 实例化一次时,您有 operator== 的两个定义 .

    • operator== 移出类声明 .

    • 请注意 friend 不是会员 . 因此,访问违规相关的诊断 .

    试试这个:

    template<typename T>
    class Wrapper {
      // Base type, which must have a val() method to allow comparison
      T t_;
    public:
      Wrapper(const T& t) : t_(t) {}
    
      // Comparison operator
    
      template<typename A, typename B>
      friend bool
      operator==(const Wrapper<A> &a, const Wrapper<B>&b);
    };
    
    template<typename A, typename B>
      bool
      operator==(const Wrapper<A> &a, const Wrapper<B>&b) {
        return a.t_.val()==b.t_.val();
      }
    
    // First example type for Wrapper
    class X {
      int x_;    
    public:
      X(int x) : x_(x) {}
    
      int
      val() const {return x_;}
    };
    
    // Second example type for Wrapper
    class Y {
      int y_;
    public:
      Y(int y) : y_(y) {}
    
      int
      val() const {return 2*y_;}
    };
    
    int
    main() {
      Wrapper<X> WX(X(4));
      Wrapper<Y> WY(Y(2));
      return ::operator==(WX, WY) ? 1 : 0;
    }
    

    虽然我仍然不喜欢那里潜伏着两个可能性的可能性......

相关问题