D 模板约束内的模式匹配

D 模板约束内的模式匹配,d,D,这个问题是基于安德烈对他的回答 我不明白为什么代码会产生编译错误。有什么想法吗?首先,我不建议使用裸模板来生成对象/结构的实例,因为您本质上要求对象是可CTFE的。如果您需要一个实例,最好的选择是从模板函数返回它: @property S!(a, b) s(int a, int b)() { return S!(a, b)(); } 但是,这似乎仍然不能与模板约束一起工作。我认为这一定是一个前端错误。据我所知,返回的类型似乎无法在is()表达式中正确检查,除非它已在其他地方实例化,例如

这个问题是基于安德烈对他的回答


我不明白为什么代码会产生编译错误。有什么想法吗?

首先,我不建议使用裸模板来生成对象/结构的实例,因为您本质上要求对象是可CTFE的。如果您需要一个实例,最好的选择是
从模板函数返回它:

@property S!(a, b) s(int a, int b)()
{
    return S!(a, b)();
}
但是,这似乎仍然不能与模板约束一起工作。我认为这一定是一个前端错误。据我所知,返回的类型似乎无法在is()表达式中正确检查,除非它已在其他地方实例化,例如:

struct S(int x, int y) 
{
    void fun(T)(T t) 
        if (is(T U == S!(a, b), int a, int b))
    {

    }
}

@property S!(a, b) s(int a, int b)()
{
    return S!(a, b)();
}

void main() 
{
    auto s1 = S!(1, 1)();
    auto s2 = S!(2, 2)();  // comment out and you get errors in fun() call
    auto s3 = s!(2, 2);
    s1.fun(s3);
}
我将把它作为bug归档


编辑:归档为。

只是一个猜测:使用
别名结果不是有问题吗
when
s
也是函数名吗?哇,对typeid和类似类型的简单检查表明那里发生了一些有趣的事情。此处不需要别名s(“enum s=”就足够了),但这不是问题所在。@alfasin否,
Alias
不是问题。你可以用
@property auto s(inta,intb)(){return s!(a,b)();}
替换整个模板,你仍然会得到同样的错误。啊,我讨厌滑稽的行为变成无聊的dmd错误。出于好奇-您是如何想到检查隐式实例化的添加的?一些逻辑结论或检查dmd源代码?我知道,使用来自多个位置的相同参数实例化的模板是同一个模板实例。我不知道这是如何在内部编程的,但我的直觉是DMD收集所有实例,然后在is()表达式检查中使用这些实例,而这里s()中的模板实例没有添加到集合中。不过,这只是一个疯狂的假设。我相当肯定这是因为具有相同参数的模板会被损坏为相同的标识符,所以链接器会合并它们。当然也有一些缓存正在进行。
struct S(int x, int y) 
{
    void fun(T)(T t) 
        if (is(T U == S!(a, b), int a, int b))
    {

    }
}

@property S!(a, b) s(int a, int b)()
{
    return S!(a, b)();
}

void main() 
{
    auto s1 = S!(1, 1)();
    auto s2 = S!(2, 2)();  // comment out and you get errors in fun() call
    auto s3 = s!(2, 2);
    s1.fun(s3);
}