![](/img/trans.png)
[英](rvalue reference) VS (const lvalue reference) as function parameters in C++11
[英]C++11: Abstracting over const, volatile, lvalue reference, and rvalue reference qualified member function pointers?
C ++ 03允許您將函數參數限定為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
type”的限定符必須完全匹配那些關於它被傳遞的參數類型的那些。 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說:
錯誤:形成指向引用類型'Baz &&'的指針
但是,這不是太奇怪,因為作為GCC 4.7還沒有對參考預選賽支持this
。
我也嘗試過使用Clang 3.0,它確實有這樣的支持:
錯誤:成員指針引用非類類型'Baz &&'
那好吧。
我是否正確得出結論認為這是不可能的,並且沒有辦法在成員函數指針的“ this type
”上抽象引用限定符? 除了在您將“ this
類型”作為模板參數傳遞的特定情況下,任何其他用於抽象限定符的技術(尤其是在this
)也將受到贊賞。
(值得指出的是,如果C ++沒有區分成員函數和普通函數,這將是微不足道的:你將模板參數用作函數(指針)的參數類型,模板參數將是按原樣通過,資格賽完好無損,無需額外考慮。)
您是否考慮過專門設計模板?
您只需添加兩個版本:
template <typename Object>
struct Bar<Object&> {
typedef int (Object::*Sig)(int)&;
};
template <typename Object>
struct Bar<Object&&> {
typedef int (Object::*Sig)(int)&&;
};
然后編譯器將適當地選擇正確的特化(或回退到一般情況)。
這樣就可以避免使用const
/ volatile
,但這意味着你需要編寫代碼3次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.