簡體   English   中英

你如何獲得成員函數的類型

[英]How do you get the type of a member function

該問題的靈感來自標准[class.mem] 中的注釋

非靜態成員函數的類型為普通函數類型,非靜態數據成員的類型為普通對象類型。 沒有特殊的成員函數類型或數據成員類型。

所以,我決定測試一下

struct S
{
    using Fn = void();
    Fn foo;

    static_assert(std::is_same_v<decltype(foo), Fn>);
};

但它的錯誤decltype(foo) : invalid use of non-static member fucntion

你如何獲得成員函數的類型? 還是那張紙條只是假的?

注意:對數據成員這樣做是有效的

struct U
{
    int i;
    static_assert(std::is_same_v<decltype(i), int>);
};

注2:我不是在尋找如何通過指向成員的指針來獲取類型

template<typename>
struct NotLikeThis;
template<typename C, typename R, typename... Args>
struct NotLikeThis<R (C::*)(Args...)>
{
    using type = R(Args...);
};

標准中的注釋與此無關。

該標准明確指出您不能這樣做。

[expr.prim.id]

2只能使用表示類的非靜態數據成員或非靜態成員函數的id 表達式

(2.1)作為類成員訪問的一部分,其中對象表達式引用成員的類58或從該類派生的類,或

(2.2)形成一個指向成員的指針 ( [expr.unary.op] ),或

(2.3)如果該id 表達式表示一個非靜態數據成員並且它出現在一個未計算的操作數中。

[ 示例:

 struct S { int m; }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK

— 結束示例 ]

請注意,我強調只能使用:這些是您可以使用表示成員函數的表達式的唯一方法。 你能想出的任何其他方式都是錯誤的。

請注意,2.3 正是您想要的 - 在未評估的上下文(即: decltype )中使用S::mm是成員函數),但它特別(我會故意假設)僅適用於數據成員。

我可以想到至少一個允許這樣做的含義(見下文)。 可能還有更多。

  • 讓我們假設m被聲明為void m(); 它是S類的成員。 如果decltype(S::m)有效,則std::add_pointer<decltype(S::m)>也應該有效。
    考慮到成員函數具有隱式this參數,這第二種類型是什么? void (S::*)() ,或者像void (*)(S*) 甚至void (*)() 對我們來說,我們想要void (S::*)()可能很明顯,但是知道S::m只是一個常規函數類型,為什么add_pointer將它變成一個指向成員的指針? 它怎么可能區分它?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM