簡體   English   中英

使用 std::reference_wrapper 作為 std::map 中的鍵

[英]Using std::reference_wrapper as the key in a std::map

我在 class 層次結構中有一堆對象,並且想使用對這些對象的引用作為 map 中的鍵來制作std::map 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]++

但是,我總是從編譯器中得到一些晦澀的錯誤:

/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’

該錯誤似乎是說它無法比較兩個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>>作為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;

由於std::reference_wrapper隱式轉換為T&std::reference_wrapper隱式構造函數,它將正常工作並且符合預期。

例子

在Visual Studio 11 Beta上,我遇到了同樣的問題。 使用調用<運算符的免費版本解決了問題。

#include<map>
#include<iostream>
using namespace::std;

class Object { 
    int _n1;
public:

    Object(int n = 0):_n1(n){};
    bool operator < (const Object& rhs) const {return this->_n1 < rhs._n1;} 
    friend ostream &operator << (ostream &stream, const Object& o) { stream << o._n1 << " "; return stream;}
};

struct ObjectLess{

    bool operator()(const Object& lhs, const Object& rhs) const 
    {
        return lhs<rhs;
    }
};

int main(int argc, char* argv[])
{
    //This does not compile
    //std::map<std::reference_wrapper<const Object>, string> table;

    //Using the free function works
    std::map<std::reference_wrapper<const Object>, string, ObjectLess> table;

    Object a(1);
    Object b(2);
    Object c(3);


    table[a]="One";
    table[c]="Three";
    table[b]="Two";

    for(auto y: table){
    cout << y.first << " " << y.second.c_str() << std::endl;
}


    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM