2014-02-13 77 views
0

我正在用C++編寫,試圖在Ubuntu下編譯,而且我正在使用函數指針作爲鍵時遇到一些問題。當我定義地圖,我沒有得到任何編譯錯誤,但只要我嘗試插入一個元素,我得到一個相當羅嗦使用成員函數指針作爲鍵的C++映射問題

In file included from /usr/include/c++/4.6/string:50:0, 
       from /usr/include/c++/4.6/bits/locale_classes.h:42, 
       from /usr/include/c++/4.6/bits/ios_base.h:43, 
       from /usr/include/c++/4.6/ios:43, 
       from /usr/include/c++/4.6/ostream:40, 
       from /usr/include/c++/4.6/iostream:40, 
       from main.cpp:1: 
/usr/include/c++/4.6/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = int (MyClass::*)()]’: 
/usr/include/c++/4.6/bits/stl_tree.h:1277:4: instantiated from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = int (MyClass::*)(), _Val = std::pair<int (MyClass::* const)(), std::vector<int> >, _KeyOfValue = std::_Select1st<std::pair<int (MyClass::* const)(), std::vector<int> > >, _Compare = std::less<int (MyClass::*)()>, _Alloc = std::allocator<std::pair<int (MyClass::* const)(), std::vector<int> > >]’ 
/usr/include/c++/4.6/bits/stl_map.h:518:41: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::map<_Key, _Tp, _Compare, _Alloc>::value_type>::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = int (MyClass::*)(), _Tp = std::vector<int>, _Compare = std::less<int (MyClass::*)()>, _Alloc = std::allocator<std::pair<int (MyClass::* const)(), std::vector<int> > >, typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::map<_Key, _Tp, _Compare, _Alloc>::value_type>::other>::iterator = std::_Rb_tree_iterator<std::pair<int (MyClass::* const)(), std::vector<int> > >, std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<int (MyClass::* const)(), std::vector<int> >]’ 
main.cpp:36:51: instantiated from here 
/usr/include/c++/4.6/bits/stl_function.h:236:22: error: invalid operands of types ‘int (MyClass::* const)()’ and ‘int (MyClass::* const)()’ to binary ‘operator<’ 

這是導致上述錯誤信息的例子:

#include <iostream> 
#include <map> 
#include <vector> 

// class definition 

class MyClass 
{ 
    public: 
      int f1(void); 
      int f2(void); 
}; 

int MyClass::f1(void) 
{ 
    return 1; 
} 

int MyClass::f2(void) 
{ 
    return 2; 
} 

using namespace std; 

int main(int argc, char* argv[]) 
{ 

    // define map 
    map< int (MyClass::*)(void), vector<int> > myMap; 
    vector<int> myVector; 

    //myMap[ &MyClass::f1 ] = myVector; 

    myMap.insert(make_pair(&MyClass::f1, myVector)); 
    return 0; 
} 

可能是什麼問題?我試着插入和[]分配,我得到了同樣的錯誤。瀏覽論壇,我發現this;但這可能是問題嗎?我不認爲我需要爲函數指針定義一個運算符「<」(它們不應該像常規指針一樣嗎?)...或者我該怎麼做?

+0

類似:http://stackoverflow.com/questions/11983070/c-converting-function-pointer-to-unique-hash-key –

+0

不只是類似的,我會稱之爲「重複」.... –

+0

@MatsPetersson:是的,最初我以爲這是關於「常規」函數指針(而不是成員函數指針);投票結束爲重複。 –

回答

1

錯誤是告訴你所有你需要知道:

invalid operands of types ‘int (MyClass::* const)()’ and ‘int (MyClass::* const)()’ to binary ‘operator<’ 

您可以使用標準operator<比不上成員函數指針,所以你必須聲明你的地圖時提供自定義比較。

不幸的是,pointers to member functions cannot be compared for inequality,所以你不能在這種情況下定義比較運算符或使用std::map。我建議使用std::unordered_map,它只需要一個std::hash和平等比較,你可以做。見here for hashing,這裏是equality comparison

+0

從技術上講,它們可以用不等式('!=')進行比較,但不用排序('<'和類似的)。 – Angew

-1

您可以實現更少的< INT(MyClass的:: *常量)()>的模板專業化,就像如下:

typedef int (MyClass::*tMyClassMember)(); 
namespace std { 
    template<> 
    struct less<tMyClassMember> 
    { 
     bool operator()(const tMyClassMember& k1, const tMyClassMember& k2) const 
     { 
      auto p1 = reinterpret_cast<const intptr_t*>(&k1); 
      auto p2 = reinterpret_cast<const intptr_t*>(&k2); 
      return *p1 < *p2; 
     } 
    }; 
} 

可能有更好的方法來比較指針到成員不是「鑄造「根據this question,它們是整數,這是一個實現特定的黑客攻擊。 That questions包含有關如何做到這一點的詳細信息。

+0

這是未定義的行爲,至多。 – rubenvb

+0

嗯,這真的是一個黑客 –