Шаблоны функций D и вывод типов - PullRequest
5 голосов
/ 21 июня 2011

Рассмотрим следующий код:

module ftwr;

import std.regex;
import std.stdio;
import std.conv;
import std.traits;

S consume (S) (ref S data, Regex ! ( Unqual!(typeof(S.init[0])) ) rg)
{
    writeln (typeid(Unqual!(typeof(S.init[0]))));

    auto m = match(data, rg);
    return m.hit;
}

void main()
{
    auto data = "binary large object";
    auto rx = regex(".*");
    consume (data, rx); // this line is mentioned in the error message
}

Теперь я ожидаю, что компилятор определит, что экземпляр consume должен быть создан как

string consume!(string)(string, Regex!(char))

, но это не похоже набывает.Ошибки следующие:

func_template_with_regex.d(24): Error: template ftwr.consume(S) does not match any function template declaration
func_template_with_regex.d(24): Error: template ftwr.consume(S) cannot deduce template function from argument types !()(string,Regex!(char))

и я вижу, что типы параметров правильные ... Я пробовал некоторые варианты сигнатуры функции, например:

S consume (S) (Regex ! ( Unqual!(typeof(S.init[0])) ) rg, ref S data)

, которая нетакже не компилировать (идея состояла в том, чтобы изменить порядок аргументов) и

immutable(S)[] consume (S) (Regex ! ( S ) rg, ref immutable(S)[] data)

, который компилирует и выводит типы в порядке.Если я указываю тип явно в вызове, то есть

consume!string(data, rx);

, он также компилируется, и отладка writeln печатает char, как и ожидалось.Я что-то упускаю в правилах логического вывода, или я только что обнаружил ошибку в компиляторе?

О да:

$ dmd -v
DMD64 D Compiler v2.053
...

1 Ответ

5 голосов
/ 21 июня 2011

Я не могу сказать, является ли это ошибкой, но вот обходной путь, который не заставляет вас указывать тип или изменять порядок аргументов. Изменить подпись consume на:

S consume (S, U) (ref S data, Regex!U rg) if (is(U == Unqual!(typeof(S.init[0]))))
...