0

我正在尝试std::reference_wrapper为这些类制作一个多态向量:

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

现在我正在尝试std::reference_wrapper像这样使用:

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

输出是:

Int2Type<0>
8Int2TypeILi0EE

这是我所期望的。

但是,现在,当我取消注释时,std::cout << (x.get() == i2t_1) << "\n";我会得到

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

这让我感到困惑,因为typeid(x.get()).name()返回8Int2TypeILi0EE而不是F12Int2TypeBasevE我得到的是什么typeid(Int2TypeBase()).name();。此外which(),派生类也被调用...那么为什么x.get()inx.get() == i2t_1评估为 a Int2TypeBase

4

2 回答 2

2

您的比较运算符仅针对派生类定义,但引用包装器产生 (static) type Int2Base,因此重载决议甚至找不到您的比较运算符!

您可能需要的是形式的比较运算符

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

但是您还需要某种多态调度来执行实际比较(大概假设动态类型匹配)。

于 2017-02-24T23:00:14.523 回答
1

在编译时,编译器只能判断 x.get() 的类型是 Int2TypeBase,因为正如声明的那样,您可以将任何 Int2TypeBase 放在那里。因此在编译时,它无法确定 == 运算符是否有效。

在运行时,您放入集合中的对象引用它们的完整类型,因此 typeid 返回您期望的内容并调用正确的虚函数。

于 2017-02-24T23:00:23.983 回答