您如何获得成员函数的类型



这个问题的灵感来自标准[class.mem]

中的注释

非静态成员函数的类型是普通函数类型,非静态数据成员的类型是普通对象类型。没有特殊的成员功能类型或数据成员类型。

所以,我决定对其进行测试

struct S
{
    using Fn = void();
    Fn foo;
    static_assert(std::is_same_v<decltype(foo), Fn>);
};

但在decltype(foo)上的错误:非静态成员fucntion

的使用无效。

您如何获得成员功能的类型?还是笔记只是伪造?

注意:对数据成员这样做是有效的

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

Note2:我不是在寻找如何通过指针到会员抓取类型

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

标准的注释与此无关。

标准明确指出您无法执行此操作。

[Expr.prim.id]

2&nbsp;一种ID表达,表示类的非静态数据成员或非静态成员功能,只能使用

&nbsp;&nbsp;&nbsp;(2.1) 作为类成员访问的一部分,其中对象表达式涉及成员的类 58 或从该类派生的类或

&nbsp;&nbsp;&nbsp;(2.2) 要形成一个指向成员的指针([Expr.unary.op])或

&nbsp;&nbsp;&nbsp;(2.3) 如果该ID表达表示非静态数据成员,并且它出现在未评估的操作数中。

[示例:

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

- 结束示例 ]

请注意,我对的重视只能使用:这些是您使用表示成员函数的表达式的唯一方法。您可以提出的任何其他方式都是错误的。

请注意,2.3正是您想要的 - 在未评估的上下文中使用S::mm是成员函数)(即:decltype),但它具体(我会故意)仅适用于 data 成员。

我可以想到允许这一点的至少一个含义(见下文)。可能还有更多。

  • 让我们假设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会将其变成指针到会员?它怎么能区分它?

最新更新