D2:如何在DLL中显式实例化模板化函数?

时间:2012-01-17 04:10:29

标签: templates dllexport d

我有一个D2型模板化功能:

void AddToAry( InTy, AcTy )( in InTy[] InAry,  ref AcTy[] AcAry )  {    

    for( uint i=0; i<InAry.length; i++ )  AcAry[i] += InAry[i];                     
}

我希望显式实例化它,以便这个函数代码是 由DLL导出,用于不同的arg类型组合。

我试图用三个符合功能的装饰来做到这一点..

export {
    void  AddToAry( float,  float  );
    void  AddToAry( float,  double );
    void  AddToAry( double, double );
}

但尝试编译会产生..

AccumAry_DLL.d(37): Error: function AccumAry_DLL.AddToAry conflicts with   template AccumAry_DLL.AddToAry(InTy,AcTy) at AccumAry_DLL.d (23)

如何告诉D2 dmd编译器实例化然后从DLL导出适当类型的代码? ..   或者可能需要使用D2 mixin模板?

现在我的工作是使用显式类型代理函数。这样做 我将模板化的泛型函数重命名为不冲突,然后导出显式实例化的代理,如下所示:

export {  // Hopefuly these proxy functions will be "inlined", and ther is no real forwarding overhead.
    void AddToAry( in  float[] InAry,  ref  float[] AcAry )  { _AddToAry( InAry, AcAry ); }
    void AddToAry( in  float[] InAry,  ref double[] AcAry )  { _AddToAry( InAry, AcAry ); }
    void AddToAry( in double[] InAry,  ref double[] AcAry )  { _AddToAry( InAry, AcAry ); }
}  // end export

这有效,然后我问是否有办法确保D @编译器不构造代理的额外转发开销水平?

2 个答案:

答案 0 :(得分:0)

我想

void AddToAry!( float, float )( in float[], ref float[] );

应该可以工作,类似于C ++。 您正在尝试声明非模板函数 - 它们的签名显然与您的模板冲突。

P.S。没检查,现在只是猜测。

答案 1 :(得分:0)

确保内联发生的一种非常简单的方法是在这里简单地使用字符串mixin。 (模板混合不是真正适用的,因为它们引入了一个声明,而你需要引入一个声明。)

private enum _AddToAry = `for(size_t i = 0; i < InAry.length; i++)  AcAry[i] += InAry[i];`
extern 
{
    void AddToAry( in  float[] InAry,  ref  float[] AcAry )  { mixin(_AddToAry); }
    void AddToAry( in  float[] InAry,  ref double[] AcAry )  { mixin(_AddToAry); }
    void AddToAry( in double[] InAry,  ref double[] AcAry )  { mixin(_AddToAry); }
}

请注意,这取决于参数命名是否一致的事实。但是,如果你需要/想要改变它,你可以创建一个简单的函数,它接受参数的名称并返回一个合适的字符串。