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

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

0 голосов
/ 06 сентября 2018

Когда я работаю с моими любимыми контейнерами, я склонен к цепным операциям. Например, в известной идиоме Erase – remove :

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

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

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

#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.

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

Мои вопросы:

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

1 Ответ

0 голосов
/ 06 сентября 2018

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

Возможно.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...