Оператор |>

Diivon
Diivon

Особо про него ничего и не скажешь наверное, но я считаю это довольно приятной фичей для добавления в следующий стандарт.

Смысл в том, что при объединении вызовов методов в "цепочку" (chaining methods) порядок вычисления аргументов для этих методов не определён, если при вычислении аргументов для такого участка кода должны происходить побочные эффекты, то соответственно порядок выполнения этих эффектов также не определён

Например:

auto getForeachFunction(){
    std::cout << "getForeach called, ";
    return [](auto const & i ){std::cout << i << ' ';};
}
auto getFoldFunction(){
    std::cout << "getFold called, ";
    return [](auto & acc, auto const & i ){acc += i;};
}
auto getExecFunction(){
    std::cout << "getExec called, ";
    return [](){std::cout << '|' << std::endl;};
}

берем эти функции и применяем соответственно к нашему велосипеду

std::vector<int> v = {1,2,3,4,5,6,7,8,9};
iterateOver(v)
    .foreach(getForeachFunction())//apply function to every element in collection
    .exec(getExecFunction())     //just call function, no changes in collection
    .fold(getFoldFunction())    //accumulate this colection in single value
    .print()                   //and do something with this value

Из данных двух кусков кода можно понять что порядок вывода строк "get... called" не определен, это легко проверить и удостовериться, что это действительно так.

Однако все мы понимаем, что вместо вывода в стандартный поток в соответствующих функциях могут быть вещи куда более серьёзные.

Идея заключается в том, чтобы добавить в язык c++ такой оператор, при помощи которого можно обращаться к членам объекта или ссылки, и при этом данный оператор являлся бы точкой следования, например |> (хочу F# в мой C++).

Т.е. чтобы напирмер код выглядел так:

std::vector<int> v = {1,2,3,4,5,6,7,8,9};
iterateOver(v)
    |>foreach(getForeachFunction())//apply function to every element in collection
    |>exec(getExecFunction())     //just call function, no changes in collection
    |>fold(getFoldFunction())    //accumulate this colection in single value
    |>print()                   //and do something with this value

И при использовании такого синтаксиса стандарт бы совершенно точно гарантировал порядок вычисления аргументов для методов, да это ограничивает полёт фантазии компилятора в плане оптимизаций, но никто же не запрещает комбинировать . и |>

Или например код использования разного рода фабрик

MainFabric::getObject<ObjectType>(getParam1(), getParam2(), getParam3()).getComponent<ComponentName>(getGetComponentSetting()).doStuffWith(MainFabric::getAnotherComponent<AnotherComponentName>(getGetComponentSetting()));

побочные эффекты getParam1, getParam2, getParam3, getGetComponentSettings, getGetComponentSettings ровно как в примере выше могут выполняться в любом порядке

MainFabric::getObject<ObjectType>(getParam1(), getParam2(), getParam3())|>getComponent<ComponentName>(getGetComponentSetting())|>doStuffWith(MainFabric::getAnotherComponent<AnotherComponentName>(getGetComponentSetting()));

Но в данном коде абсолютно точно понятно, что 2-ой вызов getGetComponentSettings будет выполнен после 1-го вызова getGetComponentSettings, и тот в свою очередь будет вызван после череды вызовов getParam1,2,3.

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

-11
рейтинг
1 комментарий
dmitriy@izvolov.ru
В С++17 последовательность выполнения выражения a.b.c.d чётко определена.
open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf
Например, в ГЦЦ 7 это уже реализовано, переупорядочивания не происходит:
wandbox.org/permlink/d6eu7UhfT3L6BDJ5
Для сравнения, в ГЦЦ 6.3 вызовы переупорядочиваются так же, как в вашем примере:
wandbox.org/permlink/qaNIQ5eEOGs7Xqpw
dmitriy@izvolov.ru
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).