170 похожих чатов

Вопрос как лучше сделать? хочу проверить на ассоциативность некоторые элементы с

некоторым бинарным оператором

Условие ассоциативности:
(A ∘ B) ∘ C = A ∘ (B ∘ C)
, где A, B и C - произвольные элементы,
∘ - бинарная операция/метод или функция принимающая два аргумента;

у меня будет метод/функция/структура, которая будет проверять проверять ассоциативность бинарного оператора в связке с конкретными типами элементов, условно говоря
template <typename T1, typename T2, typename T3 /*может что-то ещё?*/>
bool is_associative(/*нужно как-то передать оператор*/) {
...
return (A ∘ B) ∘ C = A ∘ (B ∘ C);
}
передать тип просто - обычным шаблоном, а вот как передать бинарный оператор? ещё я хотел бы сделать так чтобы оператор мог быть кастомным, но это, думаю, можно разрешить специализацией/перегрузкой

у меня есть 3 условных класса:

struct A; // втутри реализовны бинарные операции, условно operator+(...) для классов B и C
struct B; // втутри реализовны бинарные операции, условно operator+(...) для классов A и C
struct C; // втутри реализовны бинарные операции, условно operator+(...) для классов A и B
+ должна быть возможность сравнивать результат вычисления левой и правой стороны условия ассоциативности

и каждый из классов определяет как н будет взаимодействовать с другим классом посредством бинарного оператора/функции/метода + каждый из классов определяет операцию сравнения с другим классом, но это не так важно, так как в комбинации (A ∘ B) ∘ C может образовываться совместный тип, и операция сравнения с другой стороной условия ассоциативности(A ∘ (B ∘ C)) будет выполняться между другими типами

допустим это будет бинарная операция +, тогда метод/структура должны проверить следующее утверждение:

(A ∘ B) ∘ C = A ∘ (B ∘ C)
(A.operator+(B)).operator+(C) == A.operator+(B.operator+(C)) + ещё 5 вариантов с перестановкой элементов A, B и C
либо
operator+(operator+(A, B), C) == operator+(A, operator+(B, C)) + ещё 5 вариантов с перестановкой элементов A, B и C

собственно как можно передать бинарную операцию/метод или функцию принимающую два аргумента?

16 ответов

23 просмотра

Смотрите: оператор T1, T2 -> Т(1_2), оператор Т(1_2), Т3 -> Т((1_2)_3), оператор Т2, Т3 -> Т(2_3), оператор Т1, Т(2_3) -> T(1_(2_3)). Итого у вас целых 4 разных оператора, а вовсе не 1, так как разные типы.

Дима-Жигальов Автор вопроса
Alexey Petrunyaka
Смотрите: оператор T1, T2 -> Т(1_2), оператор Т(1...

операторов на самом деле больше (как минимум 6), но в этом и суть вопроса, как обобщить

Дима-Жигальов Автор вопроса

в общем это работает, но нужно передавать довольно много operator+ для разных комбинаций типа, что в целом неудобно хотелось бы делать это через какой-нибудь шаблон функции, который параметризировался внутри самой функции template <typename T1, typename T2, typename T3, template <typename, typename> typename Func> bool is_associative () { Func<T1, T2>; Func<T1, T3>; Func<T2, T1>; Func<T2, T3>; Func<T3, T1>; Func<T3, T2>; // условие - затычка bool result = Func(Func(T1{5}, T2{4}), T3{7}) == Func(Func(T1{5}, T2{4}), T3{7}); return result; }; template <typename T1, typename T2> auto func(T1 lhs, T2 rhs) { return lhs + rhs; } int main() { bool result = is_associative<Obj1, Obj2, Obj3, decltype(func)(???)>(); } вот я пытался что-то сделать: https://godbolt.org/z/9jGPb6bP4

Заверни в функцию, функцию передавай, функция это если что тип данных.

Дима Жигальов
в общем это работает, но нужно передавать довольно...

надо чтобы в функцию is_associative можно было передать кучу всяких операторов, у которых разные типы на входе и выходе да?

Дима-Жигальов Автор вопроса
Alexander Karaev
Можно посмотреть в сторону std::plus

Я смотрел, но проблема в том, что его просто так не передашь, перед передачей его нужно параметризировать -> параметризированный std::plus будет работать только для одной из множества пар аргументов

Дима-Жигальов Автор вопроса
Ilya Zviagin
Заверни в функцию, функцию передавай, функция это ...

та же проблема, либо нужно создавать 6(???) параметризированных функций и передавать их, либо использовать какой-то неизвестный мне механизм

Дима-Жигальов Автор вопроса
Ilya Zviagin
Что, проблема написать 6 функций ?

написать 6 функций не проблема, но как вы себе представляете работу с таким кодом? сама функция is_associative: template <typename T1, typename T2, typename T3> bool is_associative ( T1 (*Func12)(T1,T2), T1 (*Func13)(T1,T3), T2 (*Func21)(T2,T1), T2 (*Func23)(T2,T3), T3 (*Func31)(T3,T1), T3 (*Func32)(T3,T2)) { // условие - затычка bool result = Func13(Func12(T1{5}, T2{4}), T3{7}) == Func12(T1{5}, Func23(T2{4}, T3{7})); return result; }; шаблон функции, которую нужно параметризировать: template <typename T1, typename T2> auto func(T1 lhs, T2 rhs) { return lhs + rhs; } вызов функции is_associative: bool result = is_associative<Obj1, Obj2, Obj3>(func<Obj1, Obj2>, func<Obj1, Obj3>, func<Obj2, Obj1>, func<Obj2, Obj3>, func<Obj3, Obj1>, func<Obj3, Obj2>); MRE: https://godbolt.org/z/KaMG6GaWb

Дима Жигальов
написать 6 функций не проблема, но как вы себе пре...

а вот так не подойдет? #include <iostream> #include <functional> struct A { A() = default; A(int v): val(v) {} /* A(const A& other): val(other.val) { std::cout << "copy\n"; } A(A&& other): val(other.val) { std::cout << "move\n"; } */ A& operator+=(const A& other) { val += other.val; return *this; } int val = 1; }; A operator+(A a, const A& b) { a += b; return a; } template <template <typename> typename F, typename T, typename U> auto operate(const T& a, const U& b) { return F()(a, b); } int main() { A a, b; A c = operate<std::plus>(a, b); std::cout << c.val << ' '; std::cout << operate<std::plus>(5, b).val; // 2 6 }

Дима-Жигальов Автор вопроса
дима
а вот так не подойдет? #include <iostream> #includ...

Всё оказалось проще чем могло показаться, нужно было всего лишь определить шаблонны оператор круглые скобки внутри структуры и передавать шаблон структуры как тип(странно, что нельзя передавать шаблон функции как тип) Ваш код очень помог, спасибо вам большое

Дима Жигальов
Я смотрел, но проблема в том, что его просто так н...

std::plus<> будет работать для любых пар. Это объект с перегруженным шаблонным operator()

Дима-Жигальов Автор вопроса
Alexander Karaev
std::plus<> будет работать для любых пар. Это объе...

К сожалению я сразу подумал что std::plus это обычная шаблонная функция, и не придав этому значения подумал что это не то

Дима Жигальов
К сожалению я сразу подумал что std::plus это обыч...

Идейно, твоя задача как раз решается объектами, а не функциями, так как передать можно один объект, у которого будет пачка перегруженных операторов (или один шаблонный)

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта