d别名参数的约束
原文
别名参数的约束检查是否编译时,它实例化函数字面模板.这会触发用户函数字面中的在IFTI实例化它之前无法检测到的潜在错误.
这些错误随后会导致约束失败,因为不能编译字面.约束随后会从要用的候选列表中删除匹配模板.
void f(alias a)() if (is(typeof(a()))) {}
void main()
{
f!(x => blarg);
}
__traits(compiles, a());
应移进static if测试,并带有用错误消息.而std.algorithm.all更改为使用静断:
问题,拉取
但这仍丢弃了实际的编译错误,只是说可调用对象不工作,而没有真正说明原因(如果它接受range.front作为参数,为什么不是一元判词?).或,应删除约束,会在可调用对象主体中,得到说明确切原因的内部错误.但这对重载没用.
是否有新特征来解决它呢?
假定,
__traits(callable, expr, args);
(如果expr是函数模板),它只执行IFTI,并检查expr的参数列表是否接受args.它不检查expr(args)是否实际编译,它忽略expr正文中的错误.
它不检查返回类型,因为函数块不编译且需要推导返回类型时,一般不可能.但是,与重载可调用对象参数相比,对重载可调用对象的返回类型似乎并不那么重要.
新特征可用作约束或静如条件.作为约束,可帮助确定匹配哪些重载.两个重载:
void f(alias a)()
if (__traits(callable, a, int()))
//主体将调用(int)
// 主体将调用(int,int)
void f(alias a)()
if (__traits(callable, a, int(), int()))
该特征允许即使a的主体包含错误,根据a有的参数数量选择其中一个重载.然后实例化f的一个重载,并触发内部模板错误,指出a有个内部错误.它比Phobos的现状要好得多,因为有精确的错误消息.
在模板中,我更喜欢使用静如(static if)来避免类似情况.否则,很难找到错误原因.
失败时,最好让__traits(compiles)返回错误消息,而不仅是布尔值false.然后可编写如下代码:
enum compResult = __traits(compiles, expr);
static if (compResult) // 隐式转换为极
{
doStuffWith(expr);
}
else
{
// 打印错误消息
static assert(0, compResult.message);
}
要让约束理解它,需要更改编译器,但这应该不难.可能也应让没有显式消息参数的
static assert(__traits(compiles, expr));
打印返回消息.
参考
问题是,你的约束变成:
foo(alias bar) if (__traits(compiles, exprUsingBar).hasOnlyImplementationIssues)
OnlyImplementationIssues会很乱,很难实现,且基本上重做编译器.且,如果只是串,则可能随编译器版本而更改.更改错误消息是重大更改.
好吧,如果特别想要__traits(callable)的语义,它必须变成这样.如果只想更好显示错误消息,这是本帖子所关注的,这是不必要的.
需要改进__traits(compiles),因为(1)在现有代码中广泛使用它,(2)有时__traits(compiles)有用.
浙公网安备 33010602011771号