检查符号是 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 之类的某些东西,但实际上,如果它存在,它可能就是您正在寻找的东西。
在 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 之类的某些东西,但实际上,如果它存在,它可能就是您正在寻找的东西。