Я хотел бы написать обобщенную функцию, которая могла бы принимать либо
(1) ссылку на r-значение A и возвращать построенный на движении тип B:
A a;
B b = f(std::move(A));
// use b normally and a is now empty.
или (2) ссылку на lvalue для A и возврат объекта-обертки, который оборачивает A из автоматического вывода типа:
A a;
auto b = f(A);
// a could be used normally. The type of b is of a very complex form deduced based on the implementation of f()
B bb = b.eval(); // use eval() method from the auto type to make an evaluation of the wrapper object b to effectively copy-construct bb from a.
Я могу сделать это, выполнив следующие действия:
template <typename T>
auto f(T&& t)
-> typename std::conditional
<!std::is_lvalue_reference<T>::value,
T,
decltype (t.sqrt() + (t * 2).sin()) // ideally this could be decltype(auto) to not repeat the code but this is not allowed by C++
>::type
{
T _t(std::forward<T>(t));
return _t.sqrt() + (_t * 2).sin() // T is a data type of some template expression library with lazy evaluation capability, e.g., Eigen::Matrix, hence this line will return an expression type that is composed from the types involved in the expression, i.e. sqrt, +, *, sin.
}
Мой вопроскак указано в комментариях к приведенному выше коду, как удалить повторение вычислений в вызове decltype()
без использования decltype(auto)
в качестве ключевого слова auto
запрещено в параметре шаблона std::conditional
?
Заранее спасибо!