std::reference_wrapper 和多态容器
std::reference_wrapper and polymorphic containers
我正在尝试使用 std::reference_wrapper
为这些 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;
}
};
现在我正尝试像这样使用 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()
也被称为派生的 class... 那么为什么 x.get() == i2t_1
中的 x.get()
评估为 Int2TypeBase
?
您的比较运算符仅为派生 类 定义,但引用包装器生成(静态)类型 Int2Base
,因此重载解析甚至 find 你的比较运算符!
您可能需要的是
形式的比较运算符
bool operator==(const Int2TypeBase& lhs, const Int2TypeBase& rhs)
但是您还需要某种多态分派来执行实际比较(假设动态类型匹配)。
在编译时,编译器只能判断出 x.get() 的类型是 Int2TypeBase,因为正如所声明的那样,您可以将任何 Int2TypeBase 放在那里。所以在编译时,它不能确定==运算符是否起作用。
在 运行 时,您放入集合中的对象引用了它们的完整类型,因此 typeid returns 符合您的期望并调用了正确的虚函数。
我正在尝试使用 std::reference_wrapper
为这些 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;
}
};
现在我正尝试像这样使用 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()
也被称为派生的 class... 那么为什么 x.get() == i2t_1
中的 x.get()
评估为 Int2TypeBase
?
您的比较运算符仅为派生 类 定义,但引用包装器生成(静态)类型 Int2Base
,因此重载解析甚至 find 你的比较运算符!
您可能需要的是
形式的比较运算符bool operator==(const Int2TypeBase& lhs, const Int2TypeBase& rhs)
但是您还需要某种多态分派来执行实际比较(假设动态类型匹配)。
在编译时,编译器只能判断出 x.get() 的类型是 Int2TypeBase,因为正如所声明的那样,您可以将任何 Int2TypeBase 放在那里。所以在编译时,它不能确定==运算符是否起作用。
在 运行 时,您放入集合中的对象引用了它们的完整类型,因此 typeid returns 符合您的期望并调用了正确的虚函数。