Отправка шаблонной функции в качестве аргумента шаблонной функции в D - PullRequest
5 голосов
/ 09 марта 2012

Я пытаюсь отправить функцию D sort в качестве аргумента шаблона функции pipe.Когда я использую sort без аргументов шаблона, это работает:

import std.stdio,std.algorithm,std.functional;

void main()
{
    auto arr=pipe!(sort)([1,3,2]);
    writeln(arr);
}

Однако, когда я пытаюсь использовать sort с аргументом шаблона:

import std.stdio,std.algorithm,std.functional;

void main()
{
    auto arr=pipe!(sort!"b<a")([1,3,2]);
    writeln(arr);
}

, я получаю ошибку -main.d(5): Error: template instance sort!("b<a") sort!("b<a") does not match template declaration sort(alias less = "a < b",SwapStrategy ss = SwapStrategy.unstable,Range)

Почему это происходит?sort!"b<a" работает сам по себе и имеет те же аргументы и возвращаемые типы, что и sort, так почему pipe принимает sort, но не sort!"b<a"?И есть ли правильный синтаксис для того, что я пытаюсь сделать?

ОБНОВЛЕНИЕ

ОК, я пытался обернуть функцию sort.Работает следующий код:

import std.stdio,std.algorithm,std.functional,std.array;

template mysort(string comparer)
{
    auto mysort(T)(T source)
    {
        sort!comparer(source);
        return source;
    }
}

void main()
{
    auto arr=pipe!(mysort!"b<a")([1,3,2]);
    writeln(arr);
}

Так почему же не работает оригинальная версия?это из-за дополнительных параметров шаблона sort занимает?

1 Ответ

5 голосов
/ 10 марта 2012

Да, это из-за дополнительных параметров шаблона, в частности, параметра Range.Проблема может быть уменьшена до

size_t sort2(alias f, Range)(Range range)
{
    return 0;
}
alias sort2!"b<a" u;

Создание экземпляра sort!"b<a" завершится ошибкой, поскольку диапазон не определен.Вызов функции sort2!"b<a"([1,2,3]) работает, потому что параметр [1,2,3] может сообщить компилятору тип Range: int[].Это известно как «неявная реализация шаблона функции (IFTI)».Но IFTI работает только тогда, когда он используется как функция.В вашем случае использования sort!"b<a" создается без предоставления всех параметров, что приводит к ошибке.

Это можно исправить, сделав входную функцию литеральной, что аналогично вашему решению mysort:

 auto arr = pipe!(x => sort!"b<a"(x))([1,3,2]);

Или вы можете предоставить все необходимые параметры шаблона.Это делает код очень нечитаемым.

auto arr = pipe!(sort!("b<a", SwapStrategy.unstable, int[]))([1,3,2]);
...