cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
90 stars 0 forks source link

Унарные и бинарные операторы. #201

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +2, -12 Автор идеи: post-increment

В С++ присутствуют операторы, которые используются, как унарные и как бинарные (+, *, &). Идея состоит в том, чтобы расширить использование некоторых операторов:

В текущей реализации С++ мы можем писать следующие выражения

int* pi = initialize_me();
int i = 0,j = 1,k = 2;
i = j+k;
i = +j;
i = j*k;
i = *pi;
i = j* *pi;

Парсер языка не имеет сложностей с разбором такого кода. Также мы можем писать следующие выражения

i = ~j;
i = j^k;
i = j%k;

Хотелось бы для последних операторов иметь унарные или бинарные аналоги.

i = j~k;
i = %j;
i = ^j;

Возможно для целочисленных и иных встроенных типов это (пока что) не имеет семантического смысла. Для пользовательских типов такой подход был бы интересен.

Касаемо приоритетов. Если рассмотреть таблицу http://ru.cppreference.com/w/cpp/language/operator_precedence, то все унарные (и предлагаемы тоже) префиксные операторы соответствуют строке 3.

Приоритет бинарных операторов - вопрос обсуждаемый.

С точки зрения реализации видится, что потребуется подход аналогичный для операторов +,*,&.

Как я вижу, совместимость со старым кодом не нарушается.

Вопрос того, какие операторы расширять, обсуждаем.

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

Type1 operator^(Type2 const&);
Type3 operator~(Type4 const&, Type5 const&);

Прошу написать ваше видение. Интересно, какие плюсы и минусы вы видите в этой идее.

apolukhin commented 3 years ago

smertigdon, 6 июля 2017, 16:56 Думаю, что идея не зайдёт. Все текущие унарные операторы имеют реальный смысл и без перегрузок. А что такое %x для decltype(x) == int? И я уверен, что ради такого наделять %, ^ и прочие бинарные операторы унарным смыслом не будут

post-increment, 7 июля 2017, 19:39 Ответил ниже.

post-increment, 7 июля 2017, 19:39 Дополнение и ответ smertigdon. Моё предложение рассматривает расширение в том числе бинарных операторов на унарные .

  1. Для бинарных операторов. Например, в языке D бинарный оператор ~ означает конкатенацию. Было бы неплохо иметь такую возможность. В том случае можно более легко объединять диапазоны. Я сам в основном занимаюсь математическими задачами. И если говорить в этом контексте, то объединение векторов прекрасно смотрелось бы как v3 = v1~v2; Думаю это также хорошо сочеталось бы с range library.
  2. Касаемо унарного %. Как пример. В контексте матричных операций часто бывает нужно внешнее произведение векторов, которое в коде С++ можно записать так: M = v1%v2; Если же я хочу получить квадрат,то я вынужден писать так: M = v%v; то мне хотелось бы иметь такой синтаксис: M = %v; Знание того, что в произведении вектор один и тот же может дать преимущества для реализации. На данный момент я просто написал функцию: M = outer(v); Если говорить о типах с плавающей точкой, то унарный % в контексте матричных операций соответствует возведению в квадрат. Но мне не хотелось бы настаивать на таком семантическом смысле.
  3. Как я сказал в предложении, унарные операции (пока что) не имеют семантического смысла для встроенных типов. Однако как я указал в примере выше. унарные операции можно наделить семантическим смыслом для пользовательских типов. Пусть пользователь решает. Семантический смысл для встроенных типов - это другой вопрос дизайна языка. И его на мой взгляд можно решить позже.
  4. Замечу, что ваш критерий для унарного превращается в "что такое x для decltype(x) == int?".