Модификация оператора C ++ / стратегии метапрограммирования для менее подробного синтаксиса - PullRequest
1 голос
/ 27 января 2020

Я сейчас изучаю шаблонное метапрограммирование и шаблоны выражений на C ++, поэтому в качестве упражнения я создаю библиотеку линейной алгебры, чтобы практиковать изучаемые мной концепции.

Пока моя библиотека имеет полный список перегрузок операторов, не являющихся членами, для всех бинарных операторов, которые могут быть перегружены, и имеет довольно удобный интерфейс, который легко расширяется. Одна проблема, с которой я столкнулся, заключается в том, что матричные операции часто имеют несколько вариантов. Например, для умножения есть общее умножение матриц, скалярное произведение, произведение Кроенекера, произведение Адамара, перекрестное произведение и т. Д.

Один из хитрых путей, который используется в Matlab, - это Оператор. *, используемый для умножения Адамара (и. ^, ./, et c). В этом случае язык Matlab использует. оператор как модификатор для оператора *. Тем не менее, я не знаю каких-либо механизмов в языке c ++, которые позволяют модифицировать операторы следующим образом. Есть ли какие-то чистые обходные пути для этого поведения?

Вот некоторые вещи, о которых я уже думал: перегрузки оператора

  • допускают дополнительные параметры шаблона. Однако я не совсем уверен, как воспользоваться этим в этом контексте. Например, что-то, что может быть хорошим (хотя на практике я не уверен, что для этого есть правильный синтаксис):
template<typename lhs_t, typename rhs_t, typename op_t = Gemm>
auto operator*(lhs_t lhs, rhs_t rhs)
{
    ...
}

// Operator template specializations ...

int main()
{
    Matrix<double, 2, 2> mat1(1.0, 2.0, 3.0, 4.0);
    Matrix<double, 2, 2> mat2(1.0, 2.0, 3.0, 4.0);

    mat1 * mat2; // Works
    mat1 *<Hadamard> mat2; // Error!  Syntax????
}
  • Использование SFINAE / Concepts / if constexpr и черты, чтобы модифицировать двоичные типы выражений или переносить двоичные типы выражений. Синтаксис:
Hadamard(mat1 * mat2); // Hadamard wraps or modifies binary expression created by operator*
                       // SFINAE or Concepts used to select the correct routine based on the trait set
  • Создать бесплатную двоичную функцию. Возможные синтаксисы:
Hadamard<Multiplication>(mat1, mat2);
Hadamard_Multiplication(mat1, mat2);
  • Использование функций-членов. Синтаксис:
mat1.hadamard_multiplication(mat2);

Кажется, что ни один из них не обладает таким элегантным синтаксисом, как у Matlab:

mat1 .* mat2;

Существуют ли какие-либо методы, приближающие синтаксис модификатора оператора, который Я могу рассмотреть? Или какие-либо общие методы, чтобы сделать синтаксис использования менее многословным? Если нет, то есть ли какое-либо представление о том, что что-то может быть включено в будущие версии C ++ и может быть здесь полезным?

...