繁体   English   中英

模板运算符==

[英]Templated operator ==

我本质上是一个包含std :: map的类,其中的值是shared_ptrs,其中包裹着容纳不同类型的容器。 骨架代码如下:

// Just a basic example class
class MyClass {
  public:
    explicit MyClass(int i) : mI(i) {}
    bool operator==(const MyClass& rhs) { return mI == rhs.mI; }
  private:
    int mI;
};

// A class into which key value pairs can be added where the value
// can be of a different type.
class MultipleTypeMap {

 public:

   template <typename T>
   void AddObject(const std::string& key, const T object) {
     auto ptr = make_shared<B<MyClass>>(std::move(object));
     mSharedPtrMap.insert(pair<string, shared_ptr<A>>("key", ptr));
   }
   // ...

 private:

    class A {
    public:
      virtual ~A() = default;
    };

    template<typename T>
    class B : public A {
    public:
      explicit B(const T& t) : item(t) {}
      const T item;
    };

    map<string, shared_ptr<A>> mSharedPtrMap;
};

int main() {

    MyClass m(1);
    MultipleTypeMap multiMap;
    multiMap.AddObject("test", m);

    MyClass n(1);
    MultipleTypeMap multiMap2;
    multiMap2.AddObject("test", n);

    if (multiMap == multiMap2) {
        cout << "Equal" << endl;
    }

    return 0;
}

应该如何编写MultipleTypeMap的通用==运算符,以便通过检查lhs和rhs对象具有相同数量的键,相同键和相同对象来比较mSharedPtrMap的内容,其中相同意味着==运算符键/对象的评估结果为true?

如果您键入“擦除”(后来又不知道以前存储的类型),那么所有功能都必须由基类接口提供。 因此,我们需要在每个B实现的A中的虚拟operator==

这是一个实现:

class MultipleTypeMap {

 public:
   template <typename T>
   void AddObject(const std::string& key, T object) {
     auto ptr = std::make_unique<B<T>>(std::move(object));
     mMap.emplace(key, std::move(ptr));
   }
   // ...

    bool operator==(const MultipleTypeMap& other) const
    {
        // Sizes must be equal.
        if (mMap.size() != other.mMap.size())
            return false;

        // Sizes are equal, check keys and values in order.
        auto itOther = other.mMap.begin();
        for (auto it = mMap.begin(); it != mMap.end(); ++it, ++itOther)
        {
            if (it->first != itOther->first)
                return false;
            if (*it->second != *itOther->second)
                return false;
        }
        // No differences found.
        return true;
    }
    bool operator!=(const MultipleTypeMap& rhs) const { return !(*this == rhs); }

 private:

    class A {
    public:
      virtual ~A() = default;

      virtual bool operator==(const A& other) const = 0;
      bool operator!=(const A& other) const { return !(*this == other); }
    };

    template<typename T>
    class B : public A
    {
    public:
        explicit B(const T& t) : item(t) {}

        bool operator==(const A& other) const override
        {
            const B<T>* otherB = dynamic_cast<const B<T>*>(&other);
            // If the cast fails, types are different.
            if (!otherB)
                return false;
            // Note: The above is probably slow, consider storing (on construction)
            // and checking typeids instead.

            // Check item equality.
            return item == otherB->item;
        }

        const T item;
    };

    std::map<std::string, std::unique_ptr<A>> mMap;
};

测试演示

注意:我并没有解决原始代码中的所有不一致问题。 (您是否要移动或复制构造T ?为什么当MyClass比较运算符不是const时存储const对象?)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM