Складывающиеся выражения в С++ 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
).