Шаблонный оператор неявного преобразования типа - PullRequest
0 голосов
/ 04 мая 2018

Я реализовал

template<int M, int N, typename T=double>
class matrix{
    // ...
}

и хотел бы использовать matrix<1,1,T> там, где ожидается T.

Как мне это сделать? Будет ли следующая работа?

template<typename T>
operator T(matrix<1, 1, T> mat) {
    return mat(0,0);
}

(Причина, по которой мы ожидаем встретить matrix<1,1,T>, заключается в том, что некоторые матричные выражения имеют такой тип. Например, умножение matrix<1,3> на matrix<3,1> приводит к matrix<1,1>.)

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Поместите это в определение класса:

template<int Md=M, int Nd=N, typename = std::enable_if_t<Md==1 && Nd==1>>
operator T() const {
    return (*this)(0,0);
}
0 голосов
/ 04 мая 2018

Код, который вы перечислили, не будет компилироваться, так как вы по сути пытаетесь реализовать конструктор T вне определения T; или, если это фундаментальный тип или массив, это имеет еще меньше смысла.

Вместо этого вы можете реализовать оператор приведения в своем матричном классе - либо добавив его в общий шаблон, либо специализировав matrix для M = 1 и N = 1.

Первый вариант будет выглядеть так:

template<int M, int N, typename T=double>
class matrix{
    // ...
    operator T() const {
        static_assert(M == 1 and N==1, 
            "Attempting to treat a matrix with multiple cells as a scalar");
        // code to return the single matrix element
    }
}

и второй:

template<int M, int N, typename T=double>
class matrix{
    // ...
}


template<typename T=double>
class matrix<1, 1, T>{
    // ... some code duplication here with the main template; or maybe
    // actually have different implementation banking on the fact that
    // it's really just a scalar.

    operator T() const {
        // code to return the single matrix element
    }
}

но, честно говоря, я не думаю, что я бы порекомендовал какой-либо из этих вариантов. Я бы, вероятно, сделал одно из следующего:

  • Изменить функцию, которая принимает T так, что она может «естественно» принимать матрицы 1x1 (например, с помощью шаблонов)
  • Изменить функцию, которая принимает T так, что она может «естественно» принимать любую матрицу. Многие скалярные работы имеют интересные обобщения на матрицы.
  • Откровенно расскажите о преобразовании, возможно, написав template <typename T> T as_scalar(const matrix<1,1,T> m) функцию.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...