我在类层次结构中有一堆对象,并希望std::map
使用对这些对象的引用作为映射中的键.它似乎std::reference_wrapper
正是这需要的,但我似乎无法使它工作.到目前为止我尝试过的:
class Object { // base class of my hierarchy
// most details unimportant
public
virtual bool operator< (const Object &) const; // comparison operator
};
std::map<std::reference_wrapper<const Object>, int> table;
auto it = table.find(object);
table[object] = 42;
table[object]++
Run Code Online (Sandbox Code Playgroud)
但是,我总是从编译器中得到一些模糊的错误:
/usr/include/c++/4.5.3/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::reference_wrapper<const Object>]’:
/usr/include/c++/4.5.3/bits/stl_tree.h:1522:38: instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) [with _Key = std::reference_wrapper<const Object>, _Val = std::pair<const std::reference_wrapper<const Object>, int>, _KeyOfValue = std::_Select1st<std::pair<const std::reference_wrapper<const Object>, int> >, _Compare = std::less<std::reference_wrapper<const Object> >, _Alloc = std::allocator<std::pair<const std::reference_wrapper<const Object>, int> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::reference_wrapper<const Object>, int> >]’
/usr/include/c++/4.5.3/bits/stl_map.h:697:29: instantiated from ‘std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&)[with _Key = std::reference_wrapper<const Object>, _Tp = int, _Compare = std::less<std::reference_wrapper<const Object> >, _Alloc = std::allocator<std::pair<const std::reference_wrapper<const Object>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::reference_wrapper<const Object>, int> >, key_type = std::reference_wrapper<const Object>]’
testfile.cpp:39:31: instantiated from here
/include/c++/4.5.3/bits/stl_function.h:230:22: error: no match for ‘operator<’ in ‘__x < __y’
Run Code Online (Sandbox Code Playgroud)
错误似乎是说它无法比较两个std::reference_wrapper<const Object>
对象,但它似乎应该是可能的 - std::reference_wrapper
有一个转换运算符可以隐式地将它转换为T&
(const Object &
这里),并且Object
有一个operator <
,所以为什么它不起作用?
它应该工作,这只是g ++中的一个错误?或者还有其他事情发生了吗?
如果你将比较运算符设置为自由函数(可能调用虚拟成员函数),它似乎会起作用.
如果它是一个成员函数,a < b
那么a.operator<(b);
左侧参数的实际意味着和隐式转换不会被考虑.
默认情况下std::map
使用std::less<std::reference_wrapper<const Object>>
as Compare
,但std::reference_wrapper<T>
不转发operator<()
到基础类型T
.
解决问题的最简单和最简单的选择是在地图定义中定义std::less<const Object>
(或std::greater<const Object>
),如下所示:
std::map<std::reference_wrapper<const Object>, int, std::less<const Object>> table;
Run Code Online (Sandbox Code Playgroud)
由于隐式转换std::reference_wrapper
为T&
和隐式构造函数,std::reference_wrapper
它将正常工作并按预期工作.
例子.
归档时间: |
|
查看次数: |
4623 次 |
最近记录: |