问题 如何生成像列表理解这样的向量


在C ++ 11中,

vector<string> blockPathList;
for(int i = 0; i < blockNum; i++)
{
    blockPathList.push_back(desPath + "part" + to_string(i));
}

是否有可能重写上面的代码,如列表理解,或更短,更简洁?


12815
2018-03-31 17:05


起源

什么是 blockNum 和 desPath? - Vincent Savard
看起来你正在将1种类型的列表(向量)转换为另一种。这似乎是一个工作 map 函数,我相当肯定C ++有。 - Carcigenicate
@ChenZhongPu:我的观点是那些信息应该在你的问题中,以便能够得到适当的回答。了解更多 最小,完整和可验证的例子。 - Vincent Savard
C ++是否支持列表推导?您可能正在寻找Haskell或Python - ForceBru
是 std::generate 你会感兴趣的东西(虽然在这种情况下你需要预先调整矢量大小)? - Mark Nunberg


答案:


您想使用第三方库吗? Eric Niebler's 范围-V3 允许:

std::vector<string> blockPathList =
        view::ints(0, blockNum)
        | view::transform([&desPath](int i) {
            return desPath + "part" + std::to_string(i);
        });

这就像你将要用C ++获得的功能列表理解一样。


7
2018-03-31 17:16



你弄错了,他要求更短:) - Rotem
@Rotem OP要求列表理解。 - Barry
这是一个难以理解的列表理解,但她 没有 去问问。 - Quentin


也不漂亮,但也应该完成工作:

int cur = 0;
std::vector<std::string> blockPathList(blockNum);
std::generate(blockPathList.begin(), blockPathList.end(),
        [&](){ return destPath + "part" + std::to_string(cur++); });

不幸的是

  • 要求矢量预先调整大小
  • 需要一个外部迭代变量(因为 std::generate  Generator 不接受任何争论。

你也可以使用 std::for_each

std::vector<int> nums(blockNum);
std::iota(nums.begin(), nums.end(), 0);
std::for_each(nums.begin(), nums.end(), [&](int c) {
        blockPathList.push_back(destPath + "part" + std::to_string(c));
        });

但这再次被证实是因为 std::iota 不生成范围。它使用迭代器填充现有范围,而不是在其自身中充当数字迭代器(当然,您可以通过实现或使用生成这些迭代器的东西来解决这个问题)


4
2018-03-31 18:22



如果使用,则无需预先调整矢量大小 generate_n (C ++ 11)和 back_inserter。 - Max Lybbert