如何获取模块的所有成员/功能?

时间:2015-03-28 09:11:03

标签: reflection metaprogramming d

module testmodule;

struct testmodule {}

pragma(msg, __traits(allMembers, testmodule));
pragma(msg, __traits(allMembers, .testmodule));

打印:

tuple()
tuple()

当模块中的声明具有模块名称时,我该怎么做?

2 个答案:

答案 0 :(得分:3)

对于您知道testmodule引用的结构是模块testmodule的子结构的特定情况,您可以使用:

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

我基本上猜测模块以外的任何东西都会有sizeof属性,但我可能会忘记其他一些没有sizeof的非模块符号。< / p>

答案 1 :(得分:3)

没有提供这种错误的内置机制,因为通常编译器可以自己解决这个问题,而这种必要性根本就没有预见到。

这是一个简单的库实用程序,它概括了@rcorre提出的方法(好主意!):

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")

这不如内置符号解决方案好,但应该足够实用。