c++ - 折叠表达式 : right shift initialization behavior

标签 c++ c++17 fold-expression

我对折叠表达式很感兴趣,以便更好地理解我可以在我的项目中的哪些地方使用它们。所以我选择用一个简单的方式初始化它们

(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, 等等 但确实最后一个值应该是 1 那么它也可以是 0, 0, 0, 1

最佳答案

这是因为你的弃牌是

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

arg3 >> arg41 >> 1,所以 arg3 变成 0
然后,arg2 >> arg31 >> 0,因此 arg2 变为 1
然后,arg1 >> arg21 >> 1,因此 arg1 变为 0

因此,0, 1, 0, 1

我认为这里的教训是“突变和折叠不能混合”。

关于c++ - 折叠表达式 : right shift initialization behavior,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47695379/

相关文章:

c++ - 如何实现与参数顺序无关的 std::same_as 的广义形式(即对于两个以上的类型参数)?

c++ - 为什么 *_iterators 在移除 std::iterator 后仍然需要 typedef something void?

c++ - 如何使参数推导适用于使用基类构造函数的派生类?

c++ - 运算符= : return reference vs. 值

c++ - OpenMP,并行 for 循环,bigIntegers

c++ - C++中数组的大小是否灵活?

c++ - 折叠表达式 vs 编译递归

c++ - 在赋值中折叠表达式

c++ - 在 C++ 中声明本地对象

c++ - 如何混合 32 位整数?或 : Why is there no _mm256_blendv_epi32?