如何获得成员函数的类型 [英] How do you get the type of a member function

查看:90
本文介绍了如何获得成员函数的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The question is inspired by a note in the standard [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.

所以,我决定进行测试

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

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

但在decltype(foo)处出现错误:无效使用非静态成员功能.

如何获取成员函数的类型?还是只是伪造的钞票?

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>);
};

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

Note2: I'm not looking for how to grab the type through a pointer-to-member

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]

2  一个

[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.1) 作为类成员访问的一部分,其中对象表达式引用成员的类 58 或一个类从该类派生的,或者

   (2.1) 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

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

   (2.2) to form a pointer to member ([expr.unary.op]), or

   (2.3) 如果 id-expression 表示非静态数据成员,它出现在未评估的操作数中.

   (2.3) if that id-expression denotes a non-static data member and it appears in an unevaluated operand.

[示例:

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.

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

Note that 2.3 is exactly what you want to to - to use S::m (m being a member function) in an unevaluated context (i.e.: decltype), but it specifically (and I would assume deliberately) only applies to data members.

我可以想到至少允许这样做的一种含义(请参阅下文).可能还有更多.

I can think of at least one implication of allowing this (See below). There's probably more.

  • 假设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会将其变成一个指向成员的指针?它甚至如何区分它?
  • Let's assume m is declared as void m(); and it is a member of class S. If decltype(S::m) is valid, then std::add_pointer<decltype(S::m)> should also be valid.
    Considering that member functions have the implicit this parameter, what would this second type be? void (S::*)(), or maybe something like void (*)(S*)? Or even 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? How could it even differentiate it?

这篇关于如何获得成员函数的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆