Я пытаюсь различить два типа собственных типов, используя некоторые шаблоны магии.
типы, которые являются специализацией Matrix или Array, такие как MatrixXd, VectorXd и т. Д. Эти типыимеет собственное хранилище данных.
типы, которые являются выражениями, т.е. 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) {...}