Предположим, у меня есть функция foo(x, y, z)
, которая инвариантна относительно всех перестановок своих аргументов.У меня также есть итератор it
, так что итераторы it
, it + 1
и it + 2
могут быть разыменованы.
Можно ли писать
... = foo(*it++, *it++, *it++); // (1)
вместо
... = foo(*it, *(it + 1), *(it + 2)); // (2)
?
Насколько я понимаю, технически это правильно с C ++ 17 из-за (цитируя cppreference.com и учитывая, что it
может быть необработанным указателем)
15) При вызове функции вычисления значений и побочные эффекты инициализации каждого параметра имеют неопределенную последовательность относительно вычислений значений и побочных эффектов любого другого параметра..
Порядок вычисления аргументов функции не определен, но для foo()
порядок не имеет значения.
Но является ли это приемлемым стилем кодирования?С одной стороны, (1)
приятно симметричен и подразумевает, что foo
имеет такую инвариантность, а (2)
выглядит несколько уродливо.С другой стороны, (1)
немедленно поднимает вопрос о его правильности - тот, кто читает код, должен проверить описание или определение foo
, чтобы проверить правильность вызова.
Если тело foo()
невелико, и инвариантность очевидна из определения функции. Примите ли вы (1)
?
(Возможно, этот вопрос основан на мнении. Но я не могу не задать его.)