Я пытаюсь создать игрушечный пример для деревьев выражений, используя современный C ++ 17 на основе этого поста . Код прекрасно работает для примитивных типов, таких как int
или double
. Однако, когда я пытаюсь сделать что-то вроде Eigen::Vector3d
, сборка завершается неудачно, потому что пользовательское приведение operator result_t() const
не применяется правильно (я полагаю).
Может кто-нибудь дать мне подсказку, что именнопричина сбоя?
#include <Eigen/Dense>
template <class T, class U, class Callable>
struct BinaryExpression {
const T* left {nullptr};
const U* right {nullptr};
Callable callable;
BinaryExpression(const T& t, const U& u, const Callable c)
: left(&t), right(&u), callable(c) {}
auto operator()() const
{
return callable(*left, *right);
}
using result_t = decltype(std::declval<Callable>()(std::declval<const T&>(), std::declval<const U&>()));
operator result_t() const
{
return this->operator()();
}
};
struct Plus {
template <class T, class U>
auto operator()(const T& left, const U& right) const
{
return left + right;
}
};
int main()
{
Eigen::Vector3d v1 (1, 2, 3);
Eigen::Vector3d v2 (1, 2, 3);
int num1 = 1;
double num2 = 2.4;
BinaryExpression expr(num1, num2, Plus{});
BinaryExpression expr2(num2, expr, Plus{}); // this works fine
BinaryExpression expr3(v1, v2, Plus{});
BinaryExpression expr4(expr3, v1, Plus{}); // why does this give an error?
}
Сообщение об ошибке компилятора
../main.cpp: In instantiation of ‘auto Plus::operator()(const T&, const U&) const [with T = BinaryExpression<Eigen::Matrix<double, 3, 1>, Eigen::Matrix<double, 3, 1>, Plus>; U = Eigen::Matrix<double, 3, 1>]’:
.../main.cpp:36:55: required from ‘struct BinaryExpression<BinaryExpression<Eigen::Matrix<double, 3, 1>, Eigen::Matrix<double, 3, 1>, Plus>, Eigen::Matrix<double, 3, 1>, Plus>’
.../main.cpp:63:45: required from here
.../main.cpp:47:21: error: no match for ‘operator+’ (operand types are ‘const BinaryExpression<Eigen::Matrix<double, 3, 1>, Eigen::Matrix<double, 3, 1>, Plus>’ and ‘const Eigen::Matrix<double, 3, 1>’)
return left + right;
~~~~~^~~~~~~
Я понимаю, что operator+
не определен для добавления BinaryExpression
с типом Matrix
. Тем не менее, я ожидаю, что код будет применять пользовательский приведение BinaryExpression
, которое оценивает его как Matrix
и, следовательно, вызывает operator+
для добавления двух Matrix
типов.