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 ответов

7 просмотров

Смотрите: оператор 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 это обыч...

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

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

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

Скажите, можно ли как-то "переместить" динамический массив из одной переменной в другую? Скажем, переместить из TList<> в TArray<>. Именно переместить, а не скопировать. Если ...
Eugene Krasnikov (ᴊɪɴ x)
37
комрады, че-та лыжы не едут var tmpFont: TFont; begin tmpFont:= TFont.Create; try case rgFontColor.ItemIndex of 0: tmpFont.Color:= clWindowText; 1: tmpFo...
Ed Doc
34
Is there a digital way to cut the electricity from a usb in linux? It sounds weird, but it's exactly what I need to do. I tried to simulate the unplug/replug but is not the ...
Eduard Rivas
15
М-да. Почему бы просто со stringlist не работать?
Michael Longneck
18
Интересно, нет ли какого-то способа получить из dll не адрес самой метки, а адрес со смещением?
The Bird of Hermes
54
generic procedure function test<T>(param: T); type case T of longint: NewT = word; longword: NewT = byte; end; var v1: NewT; Как это можно сделать? Чтобы у меня...
notme
21
Можно вообще написать: Person fName' lName' age'. Тогда действительно имена полей потребуются лишь в строковом виде, чтобы эти fName' и т.д. достать :-) Но разве для этого нуж...
Михаил
8
Делал задачу вот такую https://stepik.org/lesson/4985/step/9?unit=1083 получилось такое https://play.haskell.org/saved/ipKrepqe оно работает, тестов много не писал, но работае...
Fedor
22
Hello everyone I am trying to run 4 year old project and I am having this issue anyone can help?
Nitish Garg
11
преобразовать в число или в один тип?
Alexey Kulakov
11
Карта сайта