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

Pas*_* By 7 c++ language-lawyer

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

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

所以,我决定测试一下

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

    static_assert(std::is_same_v<decltype(foo), Fn>);
};
Run Code Online (Sandbox Code Playgroud)

但它的错误在于decltype(foo):无效使用非静态成员fucntion.

你如何获得成员函数的类型?或者笔记是假的?

注意:对数据成员执行此操作是有效的

struct U
{
    int i;
    static_assert(std::is_same_v<decltype(i), int>);
};
Run Code Online (Sandbox Code Playgroud)

注2:我不是在寻找如何通过指向成员的指针来获取类型

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

标准中的注释与此无关.

Cás*_*nan 1

The standard explicitly states that you can\'t do this.

\n\n
\n

[expr.prim.id]

\n \n

2  An id-expression that denotes a non-static data member or non-static member function of a class can only be used:

\n \n

   (2.1)\n as part of a class member access in which the object expression refers to the member\'s class58 or a class derived from that class, or

\n \n

   (2.2) \n 形成指向成员的指针 ( [expr.unary.op] ),或

\n\n

   (2.3) \n 如果该id 表达式 denotes a non-static data member and it appears in an unevaluated operand.

\n\n

[ 示例:\n

\n\n
struct S {\n  int m;\n};\nint i = sizeof(S::m);           // OK\nint j = sizeof(S::m + 42);      // OK\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94 结束示例\n ]

\n
\n\n

注意我强调的是只能使用: Those are the only ways that you can use an expression denoting a member function. Any other way you can come up with is ill-formed.

\n\n

请注意,2.3 正是您想要的 - 在未评估的上下文中使用S::mm作为成员函数)(即:)decltype,但它具体(并且我会故意假设)仅适用于数据 members.

\n\n

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

\n\n
    \n
  • 假设m被声明为void m();并且它是 class 的成员S。如果decltype(S::m)有效,那么std::add_pointer<decltype(S::m)>也应该有效。
    \n考虑到成员函数具有隐式this参数,\n这第二种类型是什么?void (S::*)(),或者可能是\n之类的东西void (*)(S*)?甚至void (*)()?对我们来说,我们想要的可能是显而易见的void (S::*)(),但知道这S::m只是一个常规函数类型,为什么还要add_pointer turn it into a pointer-to-member? How could it even differentiate it?
  • \n
\n