检查符号是 D 中的 [指向] 成员 function/field 的指针

Check for symbol is a [pointer to] member function/field in D

在 C++ 中,我们可以轻松检测到给定类型是指向成员的指针 function/field:

template< class T >
struct is_member_pointer : std::false_type {};

template< class T, class U >
struct is_member_pointer<T U::*> : std::true_type {};

D 中没有这样的语法(我的意思是T U::*)。而且,free函数和方法有相同的类型:

void func();

struct S
{
    int x;
    void func() {}
}

static assert(is(typeof(func) == typeof(S.func)));

所以,我的问题是:我们可以在 D 中编写一个类似于 C++ 版本的模板吗?

template is_member_of(alias M)
{
    alias T = /**/;
}

static assert(is(is_member_of!(S.func) == S));
static assert(is(is_member_of!func == void));
static assert(is(is_member_of!(S.x) == S));

尝试通过 init 对象获取函数地址:

static assert(is(typeof(&func) == typeof(&S.init.func)));

将给予:

ooo.d(9): Error: static assert:  is(void function() == void delegate()) is false

成员函数(除非它是静态的,但它不是真正的成员函数)将被键入delegate,因为它需要一个this 对象,而另一个将键入 function.

这将适用于该函数,并且您可以对变量执行类似的操作(提示:static assert: is(typeof(& x)) is false,但 static assert(is(typeof(&S.init.x)); 通过 - 注意 .init)如果您对它是否感到好奇是实际成员,具有运行时 this 要求(即不是 static)。

我将把这些信息变成模板检查作为 reader 的练习(不过提示:is(typeof(something) == delegate) 是语言中的一个东西...)

但是,如果您只想知道符号上是否有父类型,则有一种不同的方法:只需询问编译器是否有父类型!好吧,我承认代码稍长一些,以获得您的静态断言正在寻找的 void 响应,但不长:

// identity template to hack around parser limitations
// this is common when using the __traits stuff, alas.
alias I(alias T) = T;

template is_member_of(alias M) {
        // if it has a parent, return it, otherwise, return void
        static if(is(I!(__traits(parent, M))))
                alias is_member_of = I!(__traits(parent, M));
        else
                alias is_member_of = void;
}

您还可以检查父级是否是结构或 class 之类的某些东西,但实际上,如果它存在,它可能就是您正在寻找的东西。