Здравствуйте, Evgeny.Panasyuk, Вы писали:
К>>К>>auto&& d = defaults(f, mandatory, mandatory, ondemand( []()->int { foo()+bar() } )); // первые два обязательные, третий вычисляется каждый раз
К>>
EP>mandatory могут идти только в начале или вперемешку? "В начале" уже работает.
Только в начале — вперемешку непонятно, как разруливать.
А, я протупил — у тебя в defaults перечисляются только последние, необязательные аргументы. А сколько спереди обязательных — это уже следствие из сигнатуры функции.
EP>Для ленивых вычислений вырисовывается отличие от обычных defaults:
EP>Тут заимствуется и возвращается память со стэка вызывающей функции.
EP>В случае с defaults_set — такой финт не пройдёт. "Заимствование" должен делать первый operator() который вызывается.
В порядке безумной идеи: а что, если к defauls::operator() в хвост подверстать необязательный аргумент какого-то специального типа, в котором и разместить все вычисленные на месте аргументы.
Что-то вот этакое
struct the_defaults
{
function<Data&(int,Data&&)> fun;
function<int()> make_arg1;
function<Data()> make_arg2;
Data& operator() ( int i, Data&& d ) { fun(i,d); }
Data& operator() ( int i, storage<Data> s = uninitialized ) { s.init(make_arg2()); return fun(i, s.get<0>()); }
Data& operator() ( storage<int,Data> s = uninitialized ) { s.init(make_arg1(), make_arg2()); return fun(s.get<0>(), s.get<1>()); }
};
// где storage - это кортеж, чьи элементы конструируются не сразу, а во второй фазе;
// в роли storage<...> может пойти optional<tuple<...>>
int main()
{
the_defaults d = { foo, []()->int{return rand();}, []()->Data{return Data(1,2,3);} };
use(d());
}