[英]Getting the decltype of a member function?
所以下面的代碼效果很好:
void function() { }
std::cout << typeid(decltype(function)).name() << '\n';
但以下代碼無法編譯:
struct object {
void function() { }
}
std::cout << typeid(decltype(object::function)).name() << '\n';
為什么?
成員函數有一個類型,就像普通函數有一個類型一樣,對吧? 我假設它看起來像這樣:
void func(object*, void)
奇怪的是,我可以通過以下方式獲得指針:
decltype(&object::function)
最終是這樣的:
void (__thiscall object::*)(void)
如果我能得到指向它的指針,為什么我不能得到它的類型? 就像我可以使用正常功能一樣。 在獲得指向成員函數類型的指針后,我嘗試刪除指針:
template <typename T>
struct remove_pointer { using type = T; }
template <typename T>
struct remove_pointer<T*> { using type = T; }
std::cout << typeid(remove_pointer<decltype(&object::function)>::type).name() << '\n';
它不會刪除指針,但不會導致編譯失敗,它只是打印出與我不嘗試刪除指針時相同的內容。
這一切都非常令人困惑,有人可以幫我理解為什么我無法訪問成員函數的實際類型嗎?
成員指針不是指針。 要從類型中刪除一個,您需要這樣的東西:
template <typename> struct RemoveMemPtr {};
template <typename X, typename Y> struct RemoveMemPtr<X Y::*> {using type = X;};
但是,這不會為您提供任何新信息。 給定ReturnType (Class::*)(Params...)
,它將只返回ReturnType(Params...)
,類似於如何將常規函數指針類型轉換為函數。
decltype(object::function)
不能僅僅因為標准這樣說而起作用。 當你命名一個成員函數時,你必須要么立即調用它,要么形成一個指向它的指針。
成員函數在形式上確實有一個 type ,但是除了形成一個成員指針並從中剝離指針部分之外,沒有辦法確定這種類型。 它與具有相同簽名的自由函數的類型相同(不包括隱式this
參數)。 除了成員函數可以有const
/ volatile
/ &
/ &&
限定符,而自由函數不能。
作為一件瑣事,您可以使用這些類型來聲明成員函數:
using F = void(int) const;
struct A
{
F func; // void func(int) const;
};
您的remove_pointer
名稱錯誤。 它將類型“指向類object
類型T
的成員的指針”轉換為T
,它與原始類型沒有直接關系,並且與該類型的實體不兼容。 關於原始object
是對象成員的關鍵信息丟失了。 模板最好命名為remove_membership
類的名稱。
例如,它將&object::function
的類型void (object::*)()
轉換為void()
。 目前尚不清楚為什么在使用object::function
時需要void()
,因為它與void()
無論如何都不兼容。
刪除成員資格是一個重要的、通常不是有用的轉換,因此沒有內置的語法來實現它。 如果您需要它,您只需編寫一個模板即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.