std::reference_wrapper and polymorphic containers

佐手、 提交于 2019-12-25 09:09:31

问题


I am trying to make a polymorphic vector using std::reference_wrapper for these classes:

struct Int2TypeBase{
    virtual void which(){ std::cout << "Int2TypeBase" << "\n";}
};


template <int v>
struct Int2Type : public Int2TypeBase
{
    enum
    {
        value = v
    };

    void which(){ std::cout << "Int2Type<" << value  << ">""\n";}

    friend bool operator==(const Int2Type& lhs, const Int2Type& rhs){
        return lhs.v == rhs.v;
    }
};

Now I am trying to make use of std::reference_wrapper like this:

int main(){
    using namespace std;

    std::vector<std::reference_wrapper<Int2TypeBase>> v;

    Int2Type<0> i2t_1;
    v.emplace_back(i2t_1);

    auto x = v[0];
    x.get().which();

    std::cout << typeid(x.get()).name() << "\n";

    // std::cout << (x.get() == i2t_1) << "\n";
}

The output is:

Int2Type<0>
8Int2TypeILi0EE

This is what I would expect.

Now however, when I uncomment std::cout << (x.get() == i2t_1) << "\n"; I will get

invalid operands to binary expression ('Int2TypeBase' and 'Int2Type<0>')

This confuses me, as typeid(x.get()).name() returned 8Int2TypeILi0EE rather than F12Int2TypeBasevE which is what I get for typeid(Int2TypeBase()).name();. Furthermore which() also was called for the derived class... so then why does x.get() in x.get() == i2t_1 evaluate to a Int2TypeBase?


回答1:


At compile time, the compiler can only tell that the type of x.get() is Int2TypeBase, because as declared you can put any Int2TypeBase there. So at compile time, it can't determine that the == operator will work.

At run time, the objects you put in the collection reference their full type, so typeid returns what you expect and the correct virtual function is called.




回答2:


Your comparison operator is only defined for derived classes, but the reference wrapper produces (static) type Int2Base, so overload resolution does not even find your comparison operator!

What you probably need is a comparison operator of the form

bool operator==(const Int2TypeBase& lhs, const Int2TypeBase& rhs)

but then you also need to have some sort of polymorphic dispatch to perform the actual comparison (presumably assuming that the dynamic types match).



来源:https://stackoverflow.com/questions/42449620/stdreference-wrapper-and-polymorphic-containers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!