简体   繁体   English

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

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

The question is inspired by a note in the standard [class.mem]该问题的灵感来自标准[class.mem] 中的注释

The type of a non-static member function is an ordinary function type, and the type of a non-static data member is an ordinary object type.非静态成员函数的类型为普通函数类型,非静态数据成员的类型为普通对象类型。 There are no special member function types or data member types.没有特殊的成员函数类型或数据成员类型。

So, I decided to test it所以,我决定测试一下

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

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

But its an error at decltype(foo) : invalid use of non-static member fucntion .但它的错误decltype(foo) : invalid use of non-static member fucntion

How do you get the type of a member function?你如何获得成员函数的类型? Or is the note just bogus?还是那张纸条只是假的?

Note: It is valid to do this to data members注意:对数据成员这样做是有效的

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

Note2: I'm not looking for how to grab the type through a pointer-to-member注2:我不是在寻找如何通过指向成员的指针来获取类型

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

The note from the standard is irrelevant to this.标准中的注释与此无关。

The standard explicitly states that you can't do this.该标准明确指出您不能这样做。

[expr.prim.id] [expr.prim.id]

2 An id-expression that denotes a non-static data member or non-static member function of a class can only be used : 2只能使用表示类的非静态数据成员或非静态成员函数的id 表达式

(2.1) as part of a class member access in which the object expression refers to the member's class 58 or a class derived from that class, or (2.1)作为类成员访问的一部分,其中对象表达式引用成员的类58或从该类派生的类,或

(2.2) to form a pointer to member ( [expr.unary.op] ), or (2.2)形成一个指向成员的指针 ( [expr.unary.op] ),或

(2.3) if that id-expression denotes a non-static data member and it appears in an unevaluated operand. (2.3)如果该id 表达式表示一个非静态数据成员并且它出现在一个未计算的操作数中。

[ Example: [ 示例:

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

— end example ] — 结束示例 ]

Note my emphasis on can only be used : 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.你能想出的任何其他方式都是错误的。

Note that 2.3 is exactly what you want to to - to use S::m ( m being a member function) in an unevaluated context (ie: decltype ), but it specifically (and I would assume deliberately ) only applies to data members.请注意,2.3 正是您想要的 - 在未评估的上下文(即: decltype )中使用S::mm是成员函数),但它特别(我会故意假设)仅适用于数据成员。

I can think of at least one implication of allowing this (See below).我可以想到至少一个允许这样做的含义(见下文)。 There's probably more.可能还有更多。

  • Let's assume m is declared as void m();让我们假设m被声明为void m(); and it is a member of class S .它是S类的成员。 If decltype(S::m) is valid, then std::add_pointer<decltype(S::m)> should also be valid.如果decltype(S::m)有效,则std::add_pointer<decltype(S::m)>也应该有效。
    Considering that member functions have the implicit this parameter, what would this second type be?考虑到成员函数具有隐式this参数,这第二种类型是什么? void (S::*)() , or maybe something like void (*)(S*) ? void (S::*)() ,或者像void (*)(S*) Or even void (*)() ?甚至void (*)() It may be obvious to us that we want void (S::*)() , but knowing that S::m is just a regular function type, why would add_pointer turn it into a pointer-to-member?对我们来说,我们想要void (S::*)()可能很明显,但是知道S::m只是一个常规函数类型,为什么add_pointer将它变成一个指向成员的指针? How could it even differentiate it?它怎么可能区分它?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM