Reflection 如何获取模块的所有成员/函数?
印刷品:Reflection 如何获取模块的所有成员/函数?,reflection,metaprogramming,d,Reflection,Metaprogramming,D,印刷品: module testmodule; struct testmodule {} pragma(msg, __traits(allMembers, testmodule)); pragma(msg, __traits(allMembers, .testmodule)); 当模块中的声明具有模块的名称时,如何执行此操作?对于您知道的testmodule引用模块的子结构的特定情况,您可以使用: tuple() tuple() 如果您需要确定一个符号是否实际上是一个模块,下面是我快速拼
module testmodule;
struct testmodule {}
pragma(msg, __traits(allMembers, testmodule));
pragma(msg, __traits(allMembers, .testmodule));
当模块中的声明具有模块的名称时,如何执行此操作?对于您知道的
testmodule
引用模块的子结构的特定情况,您可以使用:
tuple()
tuple()
如果您需要确定一个符号是否实际上是一个模块,下面是我快速拼凑的一些东西,似乎很管用:
我基本上猜除了模块之外的任何东西都会有一个
sizeof
属性,但我可能忘记了另一种非模块符号,它没有sizeof
没有提供用于此分解的内置机制,因为通常编译器可以自己计算它,并且这种必要性根本无法预见
下面是一个简单的库实用程序,它概括了@rcorre(好主意!)提出的方法:
这比不上内置的符号解构,但应该足够实用。此处可能的答案:从您的链接:如果模块与成员共享名称,它可能会中断,如上面提到的main示例。通过使用带有一些包点的唯一模块名称来解决问题,应该可以。这就是这里的问题。“我可能忘记了一些其他类型的非模符号,它没有sizeof”变量参数列表也没有这些。还有软件包(处理方式与模块不同)。我所知道的最可靠的解决方案是:
TT!(_traits(parent,sym))[0]
for?这是一个让你别名到uu traits表达式的技巧吗?事实上,如果冲突的声明是void getmod(int i){}
,isModule就会失败。似乎是sym.stringof
被解释为`sym().stringof:“这是一个让你给一个_; traits表达式取别名的技巧吗?”-是的。语法不允许直接使用别名,但这纯粹是语法限制,通过模板别名参数传递它可以解决问题。我在第一个示例中忽略了模板约束,立即更新了答案正确的实现可能还应该支持递归遍历父级以查找模块,但这有点超出了概念验证答案的范围:)
pragma(msg, __traits(allMembers, __traits(parent, testmodule));
template isModule(alias sym) {
enum isModule = !__traits(compiles, sym.sizeof);
}
static assert(!isModule!testmodule);
static assert(isModule!(__traits(parent, testmodule)));
module getmod;
struct getmod {};
template isModule(alias sym)
{
static if (is(typeof(sym) == function))
enum isModule = false;
else
{
import std.array : startsWith;
enum isModule = sym.stringof.startsWith("module ");
}
}
template Module(alias sym)
if (isModule!sym)
{
alias Module = sym;
}
template Module(alias sym)
if (!isModule!sym)
{
import std.typetuple : TT = TypeTuple;
alias Module = TT!(__traits(parent, sym))[0];
}
pragma(msg, __traits(allMembers, Module!getmod));
// tuple("object", "getmod", "isModule", "Module", "main")