【发布时间】:2020-03-22 22:04:46
【问题描述】:
我不经常使用 std::transform,但我发现它非常有用,我开始用这个算法替换一些 for 循环。
这里有什么问题?我想保留向量 vec 的所有代码 > 100 的元素。我希望有一个新的 std::vector 有 3 个元素:133、144 和 155。但是在算法之后大小为 0。出了什么问题?
TEST_CASE("testing trasf1", "[tras1]") {
std::vector<Test2> vec {
{1,1},
{3,3},
{11,11},
{12,12},
{133,133},
{19,19},
{21,21},
{22,22},
{23,23},
{144,144},
{155,155}
};
std::vector<uint32_t> final_v {};
final_v.reserve(vec.size());
transform(begin(vec), end(vec), begin(final_v), [] (const Test2& elem) {
if ( elem.getCode() > 100)
return elem.getCode();
});
//REQUIRE(final.size() == 3);
cout << final_v.size() << endl;
for (const auto i : final_v) {
cout << i << endl;
}
}
【问题讨论】:
-
不要使用final,它是关键字。其次,在final 上调用resize 而不是reserve。或者使用 back_inserter。您将值放入空的最终值。
-
你的 lambda 似乎没有声明它的返回类型。我觉得应该是
[] (const Test2& elem) -> int {...};。 -
@rafix07 处理了您的评论
-
您的 lambda 仅在
elem.getCode() > 100时返回定义的值。请记住,lambda 的工作方式与任何其他函数相同,所有代码路径都必须返回一个值。std::transform将始终输出与输入中一样多的元素,因此final.size() == 3没有办法。我不认为(有待更正)有一个std算法可以一步完成过滤和转换,因此您要么必须使用循环,要么分两步完成. -
@Stu 我也不这么认为。使用 C++20 中的范围和视图,这将非常容易。对于转换,可以将
back_inserter与某种optional_inserter相匹配,得到std::optional<T>并在它不是nullopt 时插入。