Складывающиеся выражения в С++ 17 - Usecase для операторов сравнения

В соответствии с N4295 С++ 17 позволит мне вычислить сумму неизвестного числа аргументов таким образом:

template<typename ... T>
int sum(T...t)
{
    return (... + t);
}

В документе далее говорится, что я мог бы использовать такие операторы, как == или > вместо+. Может ли кто-нибудь придумать разумный пример того, когда я хотел бы использовать == или > в такой конструкции?

(Я понимаю, что люди могут определять == и > делать странные вещи для странных классов, но, безусловно, это нарушает хорошую практику. Написание a > b > c > d вряд ли когда-либо является хорошей идеей, не так ли?)

Ответы

Ответ 1

Я был бы интересной особенностью, если бы скопированные сравнения, где обрабатывались как в Python, где a < b < c интерпретируется как a < b and b < c с одной оценкой b. К сожалению, это не так в С++ и даже в странных случаях, операторы сравнения сгибания действительно вряд ли имеют смысл.

Обратите внимание, что было предложение (P0313), чтобы фактически удалить операторы ==, !=, <, >, <= и >= из операторов, обрабатываемых сглаживающими выражениями. Это обсуждалось на заседании комитета в июне 2016 года в Оулу. Мотивация для удаления была довольно короткой:

Операторы сравнения не имеют большого смысла в складчатых выражениях; они расширяются в выражения, которые имеют удивительные эффекты, и поэтому полезны только для dsl-метапрограммистов. [...] Было бы неплохо исправить выражения типа a < b < c. Для этого потребуется машина времени. Не повторять проблему для сгиб-выражений кажется выполнимым.

Тем не менее, предложение отклонено.

Ответ 2

В случае usecase будет шаблоны выражений, для которых операторы сравнения (например, operator ==) возвращают объект класса вместо bool.

Я тоже изо всех сил пытаюсь найти полезный пример даже здесь.

Ответ 3

Это не "прямая сворачивание только одного", а скорее "& & folded с выражением, включающим ==". Однако это решение, которое я использую для сравнения значений, и, возможно, это также приложение, которое вы имели в виду.

Это работает для меня как для g++, так и для clang++

template <typename TYPE, typename... TYPE_TAIL>
constexpr bool same_value([[maybe_unused]] TYPE value, TYPE_TAIL... value_tail)
{
  return (... && (value == value_tail));
}

static_assert(same_value(3));
static_assert(same_value(3, 3));
static_assert(!same_value(3, 1));
static_assert(same_value(3, 3, 3));
static_assert(!same_value(3, 1, 3));

int main() {}

Компиляция:

clang++ -std=c++1z testFold.cpp -o testFold

(версия: clang version 5.0.0- + rc2-1 (теги/RELEASE_500/rc2))

или

g++ -std=c++17 testFold.cpp -o testFold

(версия: g++ (Debian 7.2.0-8) 7.2.0)

[[maybe_unused]] запрещает компилятору предупреждать вас, когда same_value(one_arg) вызывается только с одним аргументом, так как в этом случае функция возвращает нейтральное значение для && & оператор (который равен true).