如何通过 D 中的 is 表达式获取 alias-this-struct 的模板参数?

How to get the template argument of an alias-this-struct via is-expression in D?

我在玩 alias this,它可以模拟 D 中结构的继承。对于我最近启动的库,我还想提供通过 is 检测正确类型的特征模板-表达式。

这是我的类型层次结构。

struct R(X) {
    S!X s;
    alias s this;
    
    this(X i) { s = i; }
}

struct S(X) {
    T a;
    alias T = X;
    alias a this;
    
    this(T t) { a = t; }
}

import std.stdio : writeln;
void main()
{
    R!int r = 3;
    S!int s = r;
    int i = r;
    writeln(r, " ", s, " ", i );
    
    static assert( is(r.s.T) && is(typeof(r) : S!(r.s.T)) );
    
    static assert( is(typeof(r) : R!X, X) );
    
    static assert( is(typeof(r) : int) && is(typeof(r) : S!int) );
    
    alias T = int;
    static assert( is(typeof(r) : S!T) );
    
    static assert(
        is(typeof(r) : S!Q, int Q) ||
        is(typeof(r) : S!Q, Q) ||
        is(typeof(r) : S!Q, r.s.T Q) ||
        is(typeof(r) : R!Q, int Q) ||
        is(typeof(r) : R!Q, r.s.T Q)
    );
}

我希望所有 static asserts 都为真,因此它能够通过模板特化来匹配通用模板参数。但实际上,最后一个static assertfalse!这不仅仅是 rdmddmd,还有 ldc2。我想,我在这里做错了。

我的问题是,如何在不使用我示例中的别名 r.s.T 的情况下从类型 S!X 中正确提取通用模板参数 X?我想通过 is-expression.

这个问题专门针对 struct。为了性能和编程经验,我不会使用 class 继承来代替 alias this。我的结构将只是一个成员字段的小包装,其主要目的是重载某些运算符。

谢谢。

您需要使用 is INSIDE static if 进行提取。

    static if(is(typeof(r) == R!Q, Q))
        pragma(msg, Q); // will print that int, you can just use Q as a type inside this branch
    else
        // not an instance of R

is(typeof(r) : R!Q, r.s.T Q) 表示 r 的类型隐式转换为 R!Q,其中 Q 是 int 类型的值。所以这就像 R!4 之类的东西。与前两行和第一行相同,他们正在寻找 Q 是一个值,而不是一个类型。只有第二项以正确的形式完全匹配它……我猜这不仅仅是因为编译器不够聪明,无法深入研究它。就像很多 is exprs 实际上在一个层次的 ask 中工作得最好——隐式转换或提取 args。在这里,它要求同时执行这两项操作,而且很可能是一个编译器错误/惰性实现。