繁体   English   中英

获取成员函数的decltype?

[英]Getting the decltype of a member function?

所以下面的代码效果很好:

void function() { }
std::cout << typeid(decltype(function)).name() << '\n';

但以下代码无法编译:

struct object {
    void function() { }
}
std::cout << typeid(decltype(object::function)).name() << '\n';

为什么?

成员函数有一个类型,就像普通函数有一个类型一样,对吧? 我假设它看起来像这样:

void func(object*, void)

奇怪的是,我可以通过以下方式获得指针:

decltype(&object::function)

最终是这样的:

void (__thiscall object::*)(void)

如果我能得到指向它的指针,为什么我不能得到它的类型? 就像我可以使用正常功能一样。 在获得指向成员函数类型的指针后,我尝试删除指针:

template <typename T>
struct remove_pointer { using type = T; }

template <typename T>
struct remove_pointer<T*> { using type = T; }

std::cout << typeid(remove_pointer<decltype(&object::function)>::type).name() << '\n';

它不会删除指针,但不会导致编译失败,它只是打印出与我不尝试删除指针时相同的内容。

这一切都非常令人困惑,有人可以帮我理解为什么我无法访问成员函数的实际类型吗?

成员指针不是指针。 要从类型中删除一个,您需要这样的东西:

template <typename> struct RemoveMemPtr {};
template <typename X, typename Y> struct RemoveMemPtr<X Y::*> {using type = X;};

但是,这不会为您提供任何新信息。 给定ReturnType (Class::*)(Params...) ,它将只返回ReturnType(Params...) ,类似于如何将常规函数指针类型转换为函数。


decltype(object::function)不能仅仅因为标准这样说而起作用。 当你命名一个成员函数时,你必须要么立即调用它,要么形成一个指向它的指针。


成员函数在形式上确实有一个 type ,但是除了形成一个成员指针并从中剥离指针部分之外,没有办法确定这种类型。 它与具有相同签名的自由函数的类型相同(不包括隐式this参数)。 除了成员函数可以有const / volatile / & / &&限定符,而自由函数不能。

作为一件琐事,您可以使用这些类型来声明成员函数:

using F = void(int) const;

struct A
{
    F func; // void func(int) const;
};

您的remove_pointer名称错误。 它将类型“指向类object类型T的成员的指针”转换为T ,它与原始类型没有直接关系,并且与该类型的实体不兼容。 关于原始object是对象成员的关键信息丢失了。 模板最好命名为remove_membership类的名称。

例如,它将&object::function的类型void (object::*)()转换为void() 目前尚不清楚为什么在使用object::function时需要void() ,因为它与void()无论如何都不兼容。

删除成员资格是一个重要的、通常不是有用的转换,因此没有内置的语法来实现它。 如果您需要它,您只需编写一个模板即可。

暂无
暂无

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

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