У меня есть такая функция:
template <typename P1, typename... Ps> constexpr auto pipe(P1 &&proc1,
Ps &&...procs) -> Cont<Cont<
Proc<typename RevProc<P1>::ArgType,
typename RevProc<typename Last<Ps...>::Type>::RetType>>> {
using T = typename RevProc<P1>::ArgType;
using U = typename RevProc<P1>::RetType;
using V = typename RevProc<typename Last<Ps...>::Type>::RetType;
return [&] (Cont<Proc<T, V>> &&pass) {
pipe(move(procs)...)([&] (Proc<U, V> &&proc2) {
pipe(move(proc1), move(proc2))(move(pass));
});
};
}
Как вы можете узнать, что объявление типа дублируется. Есть ли шанс дать этой функции подпись вроде:
template <typename P1, typename... Ps> constexpr auto pipe(P1 &&proc1,
Ps &&...procs) -> Cont<Cont<Proc<T, V>>>
и определить T
а также V
в каком-то правильном положении?
В C ++ 14 вы можете просто позволить выводить тип:
template <typename P1, typename... Ps>
constexpr auto pipe(P1 &&proc1, Ps &&...procs) {
using T = typename RevProc<P1>::ArgType;
using U = typename RevProc<P1>::RetType;
using V = typename RevProc<typename Last<Ps...>::Type>::RetType;
return Cont<Cont<Proc<T, V>>>([&](Cont<Proc<T, V>> &&pass) {
pipe(std::move(procs)...)([&](Proc<U, V> &&proc2) {
pipe(std::move(proc1), std::move(proc2))(std::move(pass));
});
});
}
Кстати, некоторые из ваших использований std::move
не выглядит законным, так как pipe
может быть вызвано с lvalue, из которого вызывающая сторона не ожидает перемещения. Лучше на самом деле переслать то, что вы берете, перенаправив ссылку:
return Cont<Cont<Proc<T, V>>>([&](Cont<Proc<T, V>> &&pass) {
pipe(std::forward<Ps>(procs)...)([&](Proc<U, V> &&proc2) {
pipe(std::forward<P1>(proc1), std::move(proc2))(std::move(pass));
});
});
Других решений пока нет …