operator ==类型擦除容器

时间:2016-02-02 22:49:38

标签: c++ c++11 operator-overloading type-erasure

考虑以下类包装容器 type-erase 的类型:

operator==

我想将C添加到课程C 在内部,它应该只是在底层容器上调用相同的操作符,但我仍然坚持这个问题,因为我不知道该怎么做。
我们的想法是,如果operator==的基础容器的true返回<script> function clearInput() { $("#register-form :input").each( function() { $(this).val(''); }); } $(document).ready(function() { $("#register-form").submit(function(e) { //console.log($(this).attr("action")); $.ajax({ url: $(this).attr("action"), type: 'post', data: $(this).serialize(), success: function(response) { // console.log(response); $("#signin-test").html(response); clearInput(); }, error: function(response) { console.log(response); } }); e.preventDefault(); }); }); </script> ,则wb.WorkSheets(1).UsedRange.Copy activeWB.WorkSheets("Sheet1").Range("A1") 的两个实例是相等的。

无论我到现在为止尝试过什么,我最终都无法获得两个底层容器中的一个,主要是 other 中的一个。
是否有一个我目前看不到的简单解决方案,或者我应该放弃?

2 个答案:

答案 0 :(得分:0)

尽管来自 juanchopanza 的好建议,我发现,只要底层容器代表相同的概念(例如,矢量的不同特化),也许不需要 type-erase d iterator。

下面是一个可能的实现,它依赖于operator[]size成员方法:

#include <vector>
#include <cassert>

class Clazz final {
    struct BaseContainer {
        virtual std::size_t size() const noexcept = 0;
        virtual int operator[](std::size_t) const = 0;
        virtual void push_back(int) = 0;
    };

    template<class Allocator>
    struct Container: public BaseContainer {
        Container(Allocator alloc): v{alloc} { }
        std::size_t size() const noexcept override { return v.size(); }
        int operator[](std::size_t pos) const override { return v[pos]; }
        void push_back(int e) override { v.push_back(e); }

    private:
        std::vector<int, Allocator> v;
    };

public:
    template<class Allocator = std::allocator<int>>
    Clazz(const Allocator &alloc = Allocator{})
        : container{new Container<Allocator>{alloc}} { }

   ~Clazz() { delete container; }

    void push_back(int e) { container->push_back(e); }

    bool operator==(const Clazz &other) const noexcept {
        const BaseContainer &cont = *container;
        const BaseContainer &oCont = *(other.container);
        bool ret = (cont.size() == oCont.size());

        for(std::vector<int>::size_type i = 0, s = cont.size(); i < s && ret; i++) {
            ret = (cont[i] == oCont[i]);
        }

        return ret;
    }

    bool operator!=(const Clazz &other) const noexcept {
        return !(*this == other);
    }

private:
    BaseContainer *container;
};

int main() {
    Clazz c1{}, c2{}, c3{};
    c1.push_back(42);
    c2.push_back(42);
    assert(c1 == c2);
    assert(c1 != c3);
}

公开批评,希望这个答案可以帮助其他用户。 : - )

答案 1 :(得分:-2)

假设您希望在比较两个不同的容器时返回false,这应该可以完成工作(小心:未经测试):

class Container
{
    struct Concept
    {
        virtual ~Concept() = default;
        virtual Concept* clone() const = 0;

        virtual bool equals(Concept const*) const = 0;
    };

    template<typename T>
    struct Model final : Concept
    {
        Model(T t) : data{std::move(t)} {}
        Model* clone() const override { return new Model{*this}; }

        virtual bool equals(Concept const* rhs) const override
        {
            if (typeid(*this) != typeid(*rhs))
                return false;

            return data == static_cast<Model const*>(rhs)->data;
        }

        T data;
    };

    std::unique_ptr<Concept> object;

public:
    template<typename T>
    Container(T t) : object(new Model<T>{std::move(t)}) {}

    Container(Container const& that) : object{that.object->clone()} {}
    Container(Container&& that) = default;

    Container& operator=(Container that)
    { object = std::move(that.object); return *this; }

    friend bool operator==(Container const& lhs, Container const& rhs)
    { return lhs.object->equals(rhs.object.get()); }
};