Пример шаблона шаблонов выражений: пользовательское приведение не применяется для сложных типов - PullRequest
3 голосов
/ 05 ноября 2019

Я пытаюсь создать игрушечный пример для деревьев выражений, используя современный 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 типов.

1 Ответ

0 голосов
/ 05 ноября 2019

строка 47 заключается в том, что они не знают тип переменных «left» и «right». Если вы добавите int со строкой, он выдаст ошибку.

...