0

I am having fun with the fold expressions to understand better where I will be able to use them in my projects. So I choose to initialize them with a simple

(datas = ... = 1);

So far everything work as expected, every value is at 1. Then I tryed to use the left shift initialization so:

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

Here is also work as I expect it, it increase by a power of 2 it's nice. And finally I tryed this:

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

And it give me as output a 0, 1, 0, 1, 0, 1, ..., I expected it would be all at 0. So here the code:

#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;
}

Why it is 0, 1, 0, 1 etc instead of 0, 0, 0, 0 ? I through for every argument it will do more something like that: arg1 >>= arg2, arg2 >>= arg3, arg3 >>= arg4, etc but it's true that then the last value should be 1 then so it could also be 0, 0, 0, 1.

2 Answers2

5

It is that way because your fold is

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

arg3 >> arg4 is 1 >> 1, so arg3 becomes 0.
Then, arg2 >> arg3 is 1 >> 0, so arg2 becomes 1.
Then, arg1 >> arg2 is 1 >> 1, so arg1 becomes 0.

Thus, 0, 1, 0, 1.

I think the lesson here is "mutations and folds don't mix".

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
1

(datas >>= ...) is equivalent to d1 >>= (d2 >>= (d3 >>= d4));

proof:

#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;
}

expected results:

0 1 0 1 
0 1 0 1 

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

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142