2016-12-06 54 views
6
#include <iostream> 
#include <deque> 

using namespace std; 
main() 
{ 
    typedef void (deque<int>::*func_ptr)(int); 
    func_ptr fptr = &deque<int>::push_back; 
} 

我試着去獲取指向這個功能,但我得到一個編譯錯誤指針雙端隊列<int> ::的push_back

error: cannot convert ‘void (std::deque<int>::*)(const value_type&) {aka void (std::deque<int>::*)(const int&)}’ to ‘func_ptr {aka void (std::deque<int>::*)(int)}’ in initialization 
    func_ptr fptr = &deque<int>::push_back; 

我想這樣做,這樣我可以指向不同的成員函數上不同條件的基礎。

我提到this link

+0

您已鏈接的講義不再公開。 – ti7

+0

@ ti7我仍然可以訪問它。 – harman786

回答

1

push_back()需要const T &參數,如錯誤消息指出:

不能將「無效(的std :: deque的:: *)(const的VALUE_TYPE &)...

變化您的類別別名爲:

typedef void (deque<int>::*func_ptr)(const int &); 
+1

或寫'auto' ... –

+2

@LightnessRacesinOrbit - 使用'auto'將會是一個編譯錯誤,因爲函數被重載,並且auto不會知道哪個超載與給定的函數名稱關聯。 – cyberbisson

-1

您嘗試執行的操作存在更大的問題。允許實現將默認參數添加到任何成員函數,因此push_back()的實際簽名可能不同。它甚至可以添加具有相同名稱的其他功能(但簽名不同)。

我建議不要採用指向容器成員函數的指針。沒有它你通常會更好。

+0

介意downvoter解釋原因? – SergeyA

+0

我沒有投票給你,但我懷疑原因是因爲響應沒有解決OP如何獲得指向這個函數的指針的原始問題。很可能,一個答案加上你對OP的方法的禁止可能會被單獨留下。再次,我沒有這樣做。 :) – cyberbisson

3

如所述在接受的答案,問題是該類型的簽名是不同的 - 用於std::deque<T>push_back僅具有接受T const&,而不是直接T過載。 typedef void (deque<int>::*func_ptr)(const int &)是一個完美的簡潔和強大的方式來寫這個。

我想解決一個C++ 11的方式來做到這一點 - 型別名。人們可能首先想知道「爲什麼不使用auto?」這是不可能的,因爲被訪問的函數是一個重載函數,並且auto不知道要訪問哪些重載。由於原始問題嵌入了功能類型爲void(int)的知識,因此語句&deque<int>::push_back選擇了正確的過載。簡單陳述的問題在於,它會了解容器的知識和包含的類型。如果您想更改爲std::vectorintshort,則必須製作所有新類型。隨着類型別名,我們可以模板化的一切,以避免嵌入型知識:

using func_ptr = void(Cont::*)(typename Cont::const_reference); 

我們可以做一些簡單的,像以前一樣:

func_ptr<deque<int>> fptr = &deque<int>::push_back; 

...或者我們可以參考一個容器的地方:

vector<short> container; 

...查找其在編譯時類型,存儲指向其push_back功能,所有而不關心容器是什麼:

using container_type = decltype(container); 
func_ptr<container_type> fptr2 = &container_type::push_back;