функция шаблона автоматически возвращает тип с помощью std :: conditional - PullRequest
0 голосов
/ 07 декабря 2018

Я хотел бы написать обобщенную функцию, которая могла бы принимать либо

(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?

Заранее спасибо!

1 Ответ

0 голосов
/ 07 декабря 2018

Нет повторяющихся вычислений, только дублирование кода.Дублирования кода можно избежать с помощью функции.

template <typename T>
auto f(T&& t)
 -> typename std::conditional
          <!std::is_lvalue_reference<T>::value,
           T,
           decltype (function(t))
          >::type
{
    T _t(std::forward<T>(t));
    return function(_t);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...