Нарушающий порядок оценки

Когда я работаю со своими любимыми контейнерами, я склонен к цепным операциям. Например, в хорошо известной Стереть-удалить идиому:

v.erase( std::remove_if(v.begin(), v.end(), is_odd), v.end() );

Из того, что я знаю о порядке оценки, v.end() (на rhs) могут быть оценены до призыв к std::remove_if, Это не проблема здесь, так как std::remove* только перемешать вектор без изменения его конечного итератора.

Но это может привести к действительно удивительным конструкциям, как, например, (демонстрация):

#include <iostream>

struct Data
{
int v;
int value() const { return v; }
};

auto inc(Data& data)           { return ++data.v; }
void print_rhs(int, int value) { std::cout << value << '\n'; }

int main()
{
Data data{0};
print_rhs(inc(data), data.value()); // might print 0
}

Это удивительно, так как print_rhs называется после inc был вызван; что значит data.v является 1 когда print_rhs называется. Тем не менее, так как data.value() может быть оценено до, 0 это возможный вывод.

Я думаю, что это может быть хорошим улучшением, если порядок оценки будет менее удивительным; в частности, если аргументы функции с побочными эффектами были оценены раньше, чем без.

Мои вопросы тогда:

  • Обсуждали ли когда-нибудь это изменение или предложили в комитете по С ++?
  • Вы видите какие-либо проблемы, которые это может принести?

7

Решение

Обсуждали ли когда-нибудь это изменение или предложили в комитете по С ++?

Наверное.

Вы видите какие-либо проблемы, которые это может принести?

Да. Это может уменьшить возможности оптимизации, которые существуют сегодня, и не приносит никакой прямой выгоды, кроме возможности писать больше однострочников. Но в любом случае однострочники не очень хорошая вещь, так что это предложение, вероятно, никогда не пройдет -99 баллов.

8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]