выражение fold: поведение инициализации сдвига вправо

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

(datas = ... = 1);

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

    (datas = ... = 1);
    (datas <<= ...);

Здесь также работает, как я ожидаю, это увеличение в степени 2, это хорошо. И, наконец, я попробовал это:

(datas = ... = 1);
(datas >>= ...);

И это дает мне в качестве вывода 0, 1, 0, 1, 0, 1, ..., я ожидал, что все будет в 0. Итак, вот код:

#include <iostream>

template<typename... T>
void test(T&&... datas) {
    (datas = ... = 1);
    (datas >>= ...);
    (std::cout << ... << (std::to_string(datas) + " ")) << std::endl;
}

int main(int argc, char const *argv[])
{
    int v1, v2, v3, v4;
    test(v1, v2, v3, v4);
    return 0;
}

Почему это 0, 1, 0, 1 и т. д. вместо 0, 0, 0, 0? Я прохожу для каждого аргумента, он будет делать что-то вроде этого: arg1 >>= arg2, arg2 >>= arg3, arg3 >>= arg4, etc, но это правда, что тогда последнее значение должно быть 1, тогда оно также может быть 0, 0, 0, 1.


person Gabriel de Grimouard    schedule 07.12.2017    source источник


Ответы (2)


Это так, потому что ваша складка

arg1 >>= arg2 >>= arg3 >>= arg4;

arg3 >> arg4 равно 1 >> 1, поэтому arg3 станет 0.
Затем arg2 >> arg3 станет 1 >> 0, поэтому arg2 станет 1.
Тогда arg1 >> arg2 станет 1 >> 1, поэтому arg1 станет 0.

Таким образом, 0, 1, 0, 1.

Я думаю, что урок здесь таков: «мутации и складки несовместимы».

person molbdnilo    schedule 07.12.2017

(datas >>= ...) эквивалентно d1 >>= (d2 >>= (d3 >>= d4));

доказательство:

#include <iostream>

template<typename...Ts>
void set(Ts&&... datas)
{
    (datas = ... = 1);
}

template<typename...Ts>
void print(Ts&&... datas)
{
    (std::cout << ... << (std::to_string(datas) + " ")) << std::endl;
}

template<typename... T>
void test(T&&... datas) {
    set(datas...);
    (datas >>= ...);
    print(datas...);
}

void test2(int& d1, int& d2, int& d3, int& d4)
{
    set(d1,d2,d3,d4);
    d1 >>= (d2 >>= (d3 >>= d4));
    print(d1,d2,d3,d4);
}

int main(int argc, char const *argv[])
{
    int v1, v2, v3, v4;
    test(v1, v2, v3, v4);
    test2(v1, v2, v3, v4);
    return 0;
}

Ожидаемые результаты:

0 1 0 1 
0 1 0 1 

http://coliru.stacked-crooked.com/a/e0435451bcf8af70

person Richard Hodges    schedule 07.12.2017