Введите trait, чтобы проверить, является ли тип Eigen выражением (без хранилища) или Matrix или Array (с хранилищем)? - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь различить два типа собственных типов, используя некоторые шаблоны магии.

  1. типы, которые являются специализацией Matrix или Array, такие как MatrixXd, VectorXd и т. Д. Эти типыимеет собственное хранилище данных.

  2. типы, которые являются выражениями, т.е. CwiseBinaryOp и т. д. Это типы, которые возвращаются выражениями, такими как a + b.

Цель: цель - разрешить другое поведение для следующего шаблона функции:

template<typename T, typename Functor>
decltype(auto) func(const Functor& functor, T&& input) {
    if constexpr ([T is expression or lvalue reference of non-expression]) {
        return functor(std::forward<T>(input));
    } else /*[T is rvalue reference of non-expression]*/ {
        // update in-place
        input = functor(std::forward<T>(input));
        return std::move(input)
    }
}

Таким образом, я могу обернуть любую лямбду или функтор (примечание: этот функтор реализован аналогично [](auto&& input){return [expr]}, поэтомучто он возвращает выражение, которое основывается на вводе, который может быть, а может и не являться выражением) в func, поэтому я могу иметь выбор: работать ли над созданием выражения вокруг input или передатьданные, хранящиеся input в возвращаемом объекте при оценке выражения в зависимости от того, назову ли я func(input) или func(std::move(input)).

Есть идеи?Спасибо!

Редактировать:

Вот решение, которое я нашел:

template<typename Derived>
struct has_storage
 : std::is_base_of<Eigen::PlainObjectBase<std::decay_t<Derived> >, std::decay_t<Derived> >
{};

... //in func body:
if constexpr (std::is_lvalue_reference<T>::value || !has_storage<T>::value) {...}
...