Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 在D(LDC2)中调用模板函数时,委托被推断为无效_Templates_D_Type Inference - Fatal编程技术网

Templates 在D(LDC2)中调用模板函数时,委托被推断为无效

Templates 在D(LDC2)中调用模板函数时,委托被推断为无效,templates,d,type-inference,Templates,D,Type Inference,我有一个自定义的选项类型,使用代数编写 struct None{}; struct Some(T){ T t; alias t this; T get(){ return t; } }; alias Option(T) = Algebraic!(Some!(T), None); Option!T some(T)(T t){ return Option!T(Some!T(t)); } Option!T none(T)(){ re

我有一个自定义的
选项
类型,使用
代数
编写

struct None{};
struct Some(T){
    T t;

    alias t this;

    T get(){
        return t;
    }
};

alias Option(T) = Algebraic!(Some!(T), None);
Option!T some(T)(T t){
    return Option!T(Some!T(t));
}
Option!T none(T)(){
    return Option!T(None());
}
然后我尝试编写一些基本的便利函数:

T getValue(T,uint size)(VariantN!(size, Some!T, None) opt){
    return opt.get!(Some!T).t;
}

bool isDefined(T, uint size)(VariantN!(size, Some!T, None) opt){
    return opt.convertsTo!(Some!T);
}

A match(A,T,uint size)(VariantN!(size, Some!T, None) opt, A delegate(T) some, A delegate() none){
    if(opt.isDefined!(T,size)){
        return some(opt.getValue!(T,size));
    }else{
        return none();
    }
}
调用
match
时,编译器无法推断模板的正确参数:

 Option!int test = some(1);
 bool boolReturn = test.match((x) => false, () => true);
有误:

    Error: template util.match cannot deduce function from argument types !()(VariantN!(4LU, Some!int, None), void, bool function() pure nothrow @nogc @safe), candidates are:
src/util.d(79,3):        util.match(A, T, uint size)(VariantN!(size, Some!T, None) opt, A delegate(T) some, A delegate() none)
错误输出表明,
match
(意思是
bool delegate(int)
(x)=>false
)的第二个参数被推断为
void
。为什么?

此示例编译(都相同,但明确给出了x的类型):


如果委托中没有给出类型名称,则会将其作为模板(在错误消息中键入void),在实例化时,该模板将具有推断类型。。。。在这里,它希望被推断为类型T,它本身是一个基于参数的推断参数

问题是编译器试图推断(x)=>模板,同时推断函数调用,但不知道先做哪一个,所以看起来不够深入。如果你在任何一个地方明确提到它,它就会打破这个循环:

//工作 bool boolReturn=test.match!(bool,int)((x)=>false,()=>true)

//工作 test.match((int x)=>false)

但我不确定如何自动完成。。。我试着用不同的安排将它们分离,但还没有成功

Phobos通常通过将代理作为
alias
template参数而不是运行时参数来解决这个问题。将签名更改为:

typeof(none()) match(alias some, alias none, T, uint size)(VariantN!(size, Some!T, None) opt) {
并将呼叫更改为:

 bool boolReturn = test.match!((x) => false, () => true);
这是可以编译的,因为您将推理移动到了两个层:首先,编译器接受那些仍然以模板形式存在的委托作为参数。然后它接受
test
,并计算出其类型以推断其他参数。然后它移动到主体中,实际看到对
some
的调用,并在主体内的该点实例化其参数类型。它之所以有效,是因为推断类型是在从签名层(在主体外部)已知类型T之后完成的


但是如果不使用模板功能,那么。。。。我不知道,我认为解决方案是做两层,这样显式类型在其中一层命名,但我还没有弄清楚(tbh将停止尝试,因为我现在还有其他事情要做)。

如果委托中没有给出类型名称,它将作为模板(在错误消息中键入void)当它被实例化时,它将具有一个推断类型。。。。在这里,它希望被推断为类型T,它本身是一个基于参数的推断参数

问题是编译器试图推断(x)=>模板,同时推断函数调用,但不知道先做哪一个,所以看起来不够深入。如果你在任何一个地方明确提到它,它就会打破这个循环:

//工作 bool boolReturn=test.match!(bool,int)((x)=>false,()=>true)

//工作 test.match((int x)=>false)

但我不确定如何自动完成。。。我试着用不同的安排将它们分离,但还没有成功

Phobos通常通过将代理作为
alias
template参数而不是运行时参数来解决这个问题。将签名更改为:

typeof(none()) match(alias some, alias none, T, uint size)(VariantN!(size, Some!T, None) opt) {
并将呼叫更改为:

 bool boolReturn = test.match!((x) => false, () => true);
这是可以编译的,因为您将推理移动到了两个层:首先,编译器接受那些仍然以模板形式存在的委托作为参数。然后它接受
test
,并计算出其类型以推断其他参数。然后它移动到主体中,实际看到对
some
的调用,并在主体内的该点实例化其参数类型。它之所以有效,是因为推断类型是在从签名层(在主体外部)已知类型T之后完成的


但是如果不使用模板功能,那么。。。。我不知道,我认为解决方案是做两层,这样显式类型在其中一层命名,但我还没有弄清楚(tbh将停止尝试,因为我现在还有其他事情要做)。

两层方法很好地工作。感谢分享:)两层方法很好地工作。谢谢分享:)