Comments 6
С++ SFINAE как-то по сравнению с этим ...., да лучше не сравнивать. По крайней мере тут шаманить не нужно. D всё же похож на первого кандидата на переход с C++, когда его комитет окончательно зарубит. Уж сильно похоже его развитие на показ своего Я и игры участников комитета.
0
UFO just landed and posted this here
Спасибо за серию статей…
Не поможете решить правильно проблему? Есть задача
То, что у меня получается выглядит не очень красиво. Мне не нравятся длинноты вида
X!(ReturnType!f, ParameterTypeTuple!f)(&f, «a») но я не могу найти как компактно описать одновременно тип возвращаемого значения и аргументов для функции.
И не очень нравится что раздельно описываются функции и делегаты. Теряется краткость.
Спасибо заранее
Не поможете решить правильно проблему? Есть задача
- есть набор разных функций и делегатов, совпадающих по типам аргументов и результатов
- их нужно собрать в массив и применять какие-то однообразные действия(папример выполнить функию, получить результат,...)
То, что у меня получается выглядит не очень красиво. Мне не нравятся длинноты вида
X!(ReturnType!f, ParameterTypeTuple!f)(&f, «a») но я не могу найти как компактно описать одновременно тип возвращаемого значения и аргументов для функции.
И не очень нравится что раздельно описываются функции и делегаты. Теряется краткость.
Спасибо заранее
0
Думаю можно обойтись только делегатами и вынести в отдельную функцию создание класса.
Можно озвучить более полную задачу? А то есть маленькое чувство, что Вы стреляете из пушки по воробьям.
Правка
import std.stdio;
import std.traits;
auto f(string s) {
return s.length;
}
auto g(string s) {
return 2*s.length;
}
struct S {
auto getClosure() {
return (string s) { return 3*s.length; };
}
}
class X(R, A...) { // три точки значат, что можно это не один тип может быть, а кортеж типов
R delegate(A) g;
A a;
this(R delegate(A) g, A a) {
this.g = g;
this.a = a;
}
R run() { return g(a); }
}
auto newX(F,Args...)( F fnc, Args args )
if( isCallable!F && __traits(compiles, { fnc(args); }) )
// F может быть даже объектом с методом opCall
// с помощью __traits мы проверяем можем ли вызывать эту fnc с такими аргументами
{
return new X!( ReturnType!F, ParameterTypeTuple!F ) // тип объекта всё равно нужно задавать
( (Args a){ return fnc(a); }, args );
// в любом случае создаём делегат
}
void main() {
auto x = newX(&f, "a");
auto y = newX(&g, "ab");
auto s = S();
auto d = s.getClosure();
auto z = newX(d, "abc");
auto Z = [x,y,z];
foreach(t; Z) {
writeln(t.run());
}
}
Вариант функций создания
Вместо одной универсальной можно написать 2 специальные
auto newX(R,Args...)( R delegate(Args) fnc, Args args )
{ return new X!(R,Args)( fnc, args ); }
auto newX(R,Args...)( R function(Args) fnc, Args args )
{ return new X!(R,Args)( (Args a){ return fnc(a); }, args ); }
Можно озвучить более полную задачу? А то есть маленькое чувство, что Вы стреляете из пушки по воробьям.
Другой подход
import std.stdio;
import std.traits;
auto f(string s) {
return s.length;
}
auto g(string s) {
return 2*s.length;
}
struct S {
auto getClosure() {
return (string s) { return 3*s.length; };
}
}
auto apply(F,Args...)( F fnc, Args args )
if( isCallable!F && __traits(compiles,fnc(args)) )
{ return { return fnc(args); }; }
void main() {
auto x = apply(&f, "a");
auto y = apply(&g, "ab");
auto s = S();
auto d = s.getClosure();
auto z = apply(d, "abc");
auto Z = [x,y,z];
foreach(t; Z) {
writeln(t());
}
}
0
Цель — написание кода для future's — это обьекты которые запускают асинхронно вызов и выполнение какой-либо функции и позволяют продолжить выполнение основной ветки кода плюс ожидание результатов future в нужный момент.
Удобно бывает собрать их в массив для того, что-бы ждать всех, собрать результат выполнения всех, и т.д. Собрать в массив можно только обьекты одного типа, поэтому обьекты future должны быть одного типа.
Удобно бывает собрать их в массив для того, что-бы ждать всех, собрать результат выполнения всех, и т.д. Собрать в массив можно только обьекты одного типа, поэтому обьекты future должны быть одного типа.
например
int pause(int x) {
sleep(x);
return 0;
}
int connect(int p) {
auto c = connect_to_server('127.0.0.1', p);
if (c.connected) {
return 0;
} else {
return -1;
}
}
auto tasks = map!run([future(pause, 10), future(connect, 80)]);
writeln("wait some time for results");
sleep(1);
auto result = map!waitResult(tasks);
0
Sign up to leave a comment.
Compile-time рефлексия D