Dưới đây là một phiên bản cập nhật đó biên dịch với các phiên bản gần đây của trình biên dịch D:
/**
Return a Tuple expression of $(D Func) being
applied to every tuple argument.
*/
template Map(alias Func, args...)
{
static auto ref ArgCall(alias Func, alias arg)() { return Func(arg); }
static if (args.length > 1)
alias Map = TypeTuple!(ArgCall!(Func, args[0]), Map!(Func, args[1 .. $]));
else
alias Map = ArgCall!(Func, args[0]);
}
///
unittest
{
import std.conv;
int square(int arg)
{
return arg * arg;
}
int refSquare(ref int arg)
{
arg *= arg;
return arg;
}
ref int refRetSquare(ref int arg)
{
arg *= arg;
return arg;
}
void test(int a, int b)
{
assert(a == 4, a.text);
assert(b == 16, b.text);
}
void testRef(ref int a, ref int b)
{
assert(a++ == 16, a.text);
assert(b++ == 256, b.text);
}
int a = 2;
int b = 4;
test(Map!(square, a, b));
test(Map!(refSquare, a, b));
assert(a == 4);
assert(b == 16);
testRef(Map!(refRetSquare, a, b));
assert(a == 17);
assert(b == 257);
}
Nguồn
2012-10-17 03:55:33
thực sự sẽ không nhất thiết phải làm việc nếu biến đổi hàm trả về một kiểu khác nhau. Nhưng nếu bạn đã thực hiện nhập std.traits; ParameterTypeTuple! Gọi a; thay vì T a ;, tôi nghĩ điều đó sẽ thực hiện. –
Có một vấn đề khác: nó không hoạt động khi T chứa các loại bất biến. Tôi nghĩ cách duy nhất để làm điều này là sử dụng mixin chuỗi. Tôi đang thực hiện yêu cầu kéo cho Phobos ngay bây giờ. –
Triển khai của tôi hoạt động với các loại có các trường không thể thay đổi được: http://stackoverflow.com/a/12926873/279684 –