简体   繁体   English

模板运算符==

[英]Templated operator ==

I have what is essentially class containing a std::map where the values are shared_ptrs wrapping a container which holds different types. 我本质上是一个包含std :: map的类,其中的值是shared_ptrs,其中包裹着容纳不同类型的容器。 Skeleton code follows: 骨架代码如下:

// 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;
}

How should a generic == operator of MultipleTypeMap be written so that it compares the contents of mSharedPtrMap by checking that both the lhs and rhs objects have the same number of keys, the same keys and the same objects where same means that the == operator of the keys / objects evaluates to true? 应该如何编写MultipleTypeMap的通用==运算符,以便通过检查lhs和rhs对象具有相同数量的键,相同键和相同对象来比较mSharedPtrMap的内容,其中相同意味着==运算符键/对象的评估结果为true?

If you type erase (and later on don't know which type you previously stored), then all the functionality must be provided by the base class interface. 如果您键入“擦除”(后来又不知道以前存储的类型),那么所有功能都必须由基类接口提供。 So, we need a virtual operator== in A that is implemented in each B . 因此,我们需要在每个B实现的A中的虚拟operator==

Here is an implementation: 这是一个实现:

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;
};

Demo with tests 测试演示

Note: I didn't fix every inconsistency in the original code. 注意:我并没有解决原始代码中的所有不一致问题。 (Do you want to move or copy-construct your T ? Why store const objects when your MyClass comparison operator is not const ?) (您是否要移动或复制构造T ?为什么当MyClass比较运算符不是const时存储const对象?)

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

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