C++ 03允許您將函數參數限定爲const
,volatile
和/或左值引用(&
)。C++ 11:抽象const,volatile,左值引用和右值引用合格的成員函數指針?
C++ 11增加了一個:右值引用(&&
)。此外,C++允許您基於參數的限定符重載函數,以便在調用函數時選擇最合適的重載。
成員函數在概念上可以被認爲是一個函數,它接受一個額外的參數,其類型是對其所屬類的實例的引用。基於這個「額外參數」限定符的成員函數可以像其他任何參數一樣重載。這是通過把在限定符函數簽名的端部表示爲:
struct Foo
{
int& data(); // return a non-const reference if `this` is non-const
const int& data() const; // return a const reference if `this` is const
};
在C++ 03,const
和volatile
限定符是可能的,以及C++ 11還允許&
和&&
(&
理論上可以有被允許在C++ 03中,但它不是)。
可以使用限定符的任意組合,但&
和&&
是互斥的,這使C++ 03中的2^2 = 4個可能性和C++ 11中的2^4-4 = 12 。
這可以是一個相當痛苦,當你想使用成員函數指針的工作,因爲他們甚至沒有一點點的多態性在這些限定:在成員函數指針的「this
類型」爲順利通過了預選賽參數必須與它傳遞的參數類型完全匹配。 C++也沒有提供明確的工具來抽象限定符。在C++ 03中,這大多是好的,因爲你必須編寫const
版本和非const
版本,沒有人關心volatile
,但是在C++ 11的病態情況下(這並不罕見)是病態的),您可能必須手動編寫多達12個重載。每個功能。
我很高興地發現,如果你是通過封裝類作爲模板參數的類型,並能從中得到一個成員函數指針的類型,const
和volatile
預選賽被允許和傳播你所期望的:
template<typename Object>
struct Bar
{
typedef int (Object::*Sig)(int);
};
Bar<Baz>; // Sig will be `int (Baz::*)(int)`
Bar<const Baz>; // Sig will be `int (Baz::*)(int) const`
Bar<volatile Baz>; // Sig will be `int (Baz::*)(int) volatile`
Bar<const volatile Baz>; // Sig will be `int (Baz::*)(int) const volatile`
這是一個很大的不必手動寫出所有的情況更好。
不幸的是,它似乎不適用於&
和&&
。
GCC 4.7說:
error: forming pointer to reference type ‘Baz&&’
但是,這不是太奇怪,因爲作爲GCC 4.7還沒有對this
參考預選賽支持。
error: member pointer refers into non-class type 'Baz &&'
呵呵,好了:
我也鐺3.0,它確實有這樣的支持試了一下。
我正確地斷定這是不可能的,並且沒有辦法在成員函數指針的「this type
」上抽象引用限定符嗎?除了在通過「this
類型」作爲模板參數時的特定情況之外,還可以使用任何其他用於限定符(尤其是this
)抽象的技術。 (值得指出的是,如果C++沒有區分成員函數和普通函數,這將會很簡單:您將使用模板參數作爲函數(指針)的參數類型,並且模板參數將按原樣傳遞,修飾符完好無損,無需額外考慮。)
對於所有可能的限定符組合,你需要多少次不同的行爲? (或者,對於這個問題,甚至有兩種或三種可能的組合) – 2012-01-15 19:49:16
如果我想爲函數類對象編寫一個抽象(本質上是std :: function但不一樣),那麼完整性是一個設計目標。我無法真正推斷或估計(至於多頻繁),但我知道我以前遇到過它。 – glaebhoerl 2012-01-15 20:25:29