D2: Как явно создать шаблонную функцию в DLL? - PullRequest
2 голосов
/ 17 января 2012

У меня есть шаблонная функция типа 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)

Как можно указать D2d-компилятору D2 создать экземпляр, а затем экспортировать соответствующий типизированный код из DLL? .. Или, возможно, вместо этого нужно использовать миксин-шаблон D2?

В настоящее время моя работа заключается в том, чтобы использовать прокси-функцию с явным типом. Сделать так Я переименовал шаблонную универсальную функцию, чтобы она не конфликтовала, а затем экспортировал явно созданные экземпляры прокси, например:

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 голосов
/ 19 января 2015

Очень простой способ убедиться, что встраивание происходит, - просто использовать здесь строковый миксин. (Шаблонные миксины на самом деле не применимы, поскольку они вводят декларацию, в то время как вам нужно вводить оператор.)

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); }
}

Обратите внимание, что это зависит от того факта, что именование аргумента является последовательным. Однако, если вам нужно / нужно изменить это значение, вы можете создать простую функцию, которая принимает имена аргументов и возвращает соответствующую строку.

0 голосов
/ 17 января 2012

Полагаю,

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

должно работать, подобно C ++.Вы пытаетесь объявить не шаблонные функции - их подпись явно конфликтует с вашим шаблоном.

PS Не проверено, пока только догадываюсь.

...