Цепные вызовы функций-членов - порядок вызовов

У меня есть большое приложение, содержащее связанные вызовы функций, например:

subsystem.
    do_stuff(cfg().get("x")).
    do_stuff(cfg().get("y"));

Здесь subsystem — объект типа класса:

struct Sybsystem
{
    Sybsystem& do_stuff(int parameter)
    {
        ... // much code
        return *this; // this line makes it possible to chain calls
    }
};

Кроме того, cfg() — это «глобальная функция», которая возвращает объект конфигурации:

struct Configuration
{
    int get(const char* param_name);
}
Configuration& cfg();

Код со связанными вызовами функций сначала работает с x, затем с y; однако C++ не определяет, когда параметры конфигурации для x и y извлекаются из объекта конфигурации. Действительно, когда я запускаю свое приложение в режиме отладки и выпуска (MS Visual Studio 2005), порядок вызовов Configuration::get противоположен.

Все было хорошо, пока мы не добавили поддержку возврата случайных значений из Configuration::get (для тестирования). Когда мы это сделали, поведение в режимах Debug и Release стало другим.

Итак, мой вопрос:

Могу ли я решить эту проблему и по-прежнему использовать связанные вызовы функций? (у нас много кода написано таким образом, было бы утомительно менять все это)

Можно ли использовать, например, трюки с volatile?


person anatolyg    schedule 29.02.2012    source источник
comment
Я немного смущен тем, как разные результаты, когда вы возвращаете случайные значения, могут быть проблемой. Конечно, результаты должны всегда быть разными?   -  person Lightness Races in Orbit    schedule 29.02.2012
comment
@LightnessRacesinOrbit Я использую генератор псевдослучайных чисел с постоянным начальным числом   -  person anatolyg    schedule 29.02.2012


Ответы (1)


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

Вам придется разорвать цепочку, чтобы создать свои собственные точки последовательности, где этот порядок важен.

person Lightness Races in Orbit    schedule 29.02.2012
comment
Этот ответ устарел. Рассматриваемая проблема была исправлена ​​в C++17. - person anatolyg; 02.02.2020