Шаблонная магия в D?

Есть множество функций с сигнатурой:

AT Func(AT arg);<br>



Хочется сделать шаблон, который бы автоматически адаптировал этот интерфейс к:

Val AdaptedFunc(A a, Val v);<br>



При наличии конструкторов:

AT(A, Val);<br>
Val(AT);<br>




То есть если писать адаптер для каждой функции вручную получится так:

Val AdaptedFunc(A a,  Val v)<br>
{<br>
	return Val(Func(AT(a, v)));<br>
}<br>




Ясно, что это совсем не то, что хочется. Пока у меня получилось с помощью mixin templates, но это тоже не то, что хочется, а хочется в результате примерно такого кода:

Val v = Adapter!Func(A a, Val v);<br>
  • Вопрос задан
  • 3472 просмотра
Пригласить эксперта
Ответы на вопрос 1
NCrashed
@NCrashed
Наверняка, спустя год решение не будет актуально, но для изучающих язык может быть полезно.

module main;

import std.stdio;
import std.traits;

Val AdaptedFunc(alias Func, A, Val)(A a, Val V)
{
	alias ReturnType!Func AT;
	static assert(__traits(compiles, AT(a,V)), AT.stringof ~ " must have constructor this("~A.stringof~","~Val.stringof~")");
	static assert(__traits(compiles, Val(AT(a,V))), Val.stringof ~ " must have constructor this("~AT.stringof~")");
	return Val(Func(AT(a,V)));
}

struct Test1 
{
	string name;
	int val;

	this(string pName, Test2 test)
	{
		name = pName;
		val = test.val;
	}
}

Test1 test1Transform(Test1 test)
{
	test.val *= test.val;
	return test;
}

struct Test2
{
	int val;

	this(Test1 pVal)
	{
		val = pVal.val;
	}
}

int main(string[] args)
{
	Test2 testA;
	testA.val = 2;
	Test2 testB = AdaptedFunc!test1Transform("first", testA);
	writeln(testB.val); // prints 4
	getchar();
	return 0;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы