Reference_wrappers 的容器(需要比较运算符?)
如果您将 stl 容器与 POD 类型的 reference_wrappers 一起使用,则如下代码可以正常工作:
int i = 0;
std::vector< boost::reference_wrapper<int> > is;
is.push_back(boost::ref(i));
std::cout << (std::find(is.begin(),is.end(),i)!=is.end()) << std::endl;
但是,如果您使用非 POD 类型,例如(人为的示例):
struct Integer
{
int value;
bool operator==(const Integer& rhs) const
{
return value==rhs.value;
}
bool operator!=(const Integer& rhs) const
{
return !(*this == rhs);
}
};
声明上面的比较运算符是不够的,您还可以必须声明:
bool operator==(const boost::reference_wrapper<Integer>& lhs, const Integer& rhs)
{
return boost::unwrap_ref(lhs)==rhs;
}
并且可能还:
bool operator==(const Integer& lhs, const boost::reference_wrapper<Integer>& rhs)
{
return lhs==boost::unwrap_ref(rhs);
}
为了使等效代码正常工作:
Integer j = { 0 };
std::vector< boost::reference_wrapper<Integer> > js;
js.push_back(boost::ref(j));
std::cout << (std::find(js.begin(),js.end(),j)!=js.end()) << std::endl;
现在,我想知道这是否真的是它应该完成的方式,因为它有点不切实际。似乎应该有一个更简单的解决方案,例如模板:
template<class T>
bool operator==(const boost::reference_wrapper<T>& lhs, const T& rhs)
{
return boost::unwrap_ref(lhs)==rhs;
}
template<class T>
bool operator==(const T& lhs, const boost::reference_wrapper<T>& rhs)
{
return lhs==boost::unwrap_ref(rhs);
}
reference_wrapper 的行为方式可能有一个很好的理由(可能是为了在没有比较运算符的情况下容纳非 POD 类型?)。也许已经有一个优雅的解决方案,只是我还没有找到。
If you use stl containers together with reference_wrappers of POD types, code such as the following works just fine:
int i = 0;
std::vector< boost::reference_wrapper<int> > is;
is.push_back(boost::ref(i));
std::cout << (std::find(is.begin(),is.end(),i)!=is.end()) << std::endl;
However, if you use non-POD types like (contrived example):
struct Integer
{
int value;
bool operator==(const Integer& rhs) const
{
return value==rhs.value;
}
bool operator!=(const Integer& rhs) const
{
return !(*this == rhs);
}
};
It doesn't suffice to declare the comparison operators above, aditionally you have to declare:
bool operator==(const boost::reference_wrapper<Integer>& lhs, const Integer& rhs)
{
return boost::unwrap_ref(lhs)==rhs;
}
And possibly also:
bool operator==(const Integer& lhs, const boost::reference_wrapper<Integer>& rhs)
{
return lhs==boost::unwrap_ref(rhs);
}
In order to get the equivalent code to work:
Integer j = { 0 };
std::vector< boost::reference_wrapper<Integer> > js;
js.push_back(boost::ref(j));
std::cout << (std::find(js.begin(),js.end(),j)!=js.end()) << std::endl;
Now, I'm wondering if this is really the way it's meant to be done, since it's somewhat impractical. It just seems there should be a simpler solution, e.g. templates:
template<class T>
bool operator==(const boost::reference_wrapper<T>& lhs, const T& rhs)
{
return boost::unwrap_ref(lhs)==rhs;
}
template<class T>
bool operator==(const T& lhs, const boost::reference_wrapper<T>& rhs)
{
return lhs==boost::unwrap_ref(rhs);
}
There's probably a good reason why reference_wrapper behaves the way it does (possibly to accomodate non-POD types without comparison operators?). Maybe there already is an elegant solution and I just haven't found it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您这样声明原始比较例程时,上面的示例是否有效:
请注意,在类中声明友元比较例程与声明成员函数比较例程不同,这就是为什么它们可能有效而原始代码可能无效的原因。
Does the example above work when you declare the original comparison routines as such:
Note that declaring a friend comparison routine in the class is not the same as declaring a member function comparison routine, which is why these may work while your original code may not.