std::for_each 优于 std::set,C++11

发布于 2024-12-15 15:44:40 字数 571 浏览 1 评论 0原文

迭代向量有效:

std::vector<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});

但不能迭代集合(编译错误):

std::set<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});

为什么我不能使用 std::for_each 迭代 std::set

奖金问题: 另外,我想将 lambda 参数中的 int& 更改为 auto&,为什么不能自动推导呢?

Iterating over a vector works:

std::vector<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});

but not over a set (compile error):

std::set<int> collection = {2, 3, 4, 5435345, 2};
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;});

Why can't I iterate over a std::set with std::for_each?

Bonus question:
Also, I would like to change the int& in the lambda's argument to auto&, why can't this be automatically deduced?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忆依然 2024-12-22 15:44:40

std::set::value_typeT const,而不是 T;因此,lambda 的参数必须是值类型(即复制)或 int const& (从技术上讲,或 int const volatile&),而不是 int&.即,这有效:

std::set<int> collection{2, 3, 4, 5435345, 2};
std::for_each(
    collection.begin(),
    collection.end(),
    [](int const& i) { std::cout << i << std::endl; }
);

额外问题:另外,我想将 lambda 参数中的 int& 更改为 auto&,为什么不能自动推导?

因为标准说不能;从历史上看,我认为这是由于 lambda 和概念之间的交互过于复杂(在概念从草案中删除之前)。 但是,我听说有传言称新 (C++11) 标准的第一个缺陷报告将准确解决这个问题,因此您可能会在明年或之内看到对此添加到您选择的编译器中的支持二. 编辑:哦,看,C++14 现在有了多态 lambda...

std::set<T>::value_type is T const, not T; consequently, the argument to your lambda must be a value type (i.e., copy) or int const& (and technically, or int const volatile&), not int&. I.e., this works:

std::set<int> collection{2, 3, 4, 5435345, 2};
std::for_each(
    collection.begin(),
    collection.end(),
    [](int const& i) { std::cout << i << std::endl; }
);

Bonus question: Also, I would like to change the int& in the lambda's argument to auto&, why can't this be automatically deduced?

Because the standard says it can't; historically, I believe this was due to overly-complicated interactions between lambdas and concepts (before concepts were removed from the draft). However, I hear rumors that the first defect reports to the new (C++11) standard will address exactly this, so it's possible that you'll see support for this added to your compiler of choice within the next year or two. EDIT: Oh, look, C++14 now has polymorphic lambdas...

余生共白头 2024-12-22 15:44:40

关于额外的问题:“auto”函数参数并非特定于 lambda。您可能还会问为什么我们不允许将所有函数声明为f(auto x, auto y)。但这仅仅意味着您本质上希望用函数模板替换所有函数。这被认为不适用于现有的 C++ 语言,尤其是类型系统。如果您想要一个函数模板,那么已经有现有的语法和机制,并且声明“自动”参数不是正确的方法。

Concerning the bonus question: An "auto" function argument isn't specific to lambdas. You might as well ask why we don't allow all functions to be declared as f(auto x, auto y). But that just means that you essentially want to replace all functions by function templates. That was considered not to work well with the existing C++ language and the type system in particular. If you want a function template, there's already an existing syntax and mechanism, and declaring "auto" arguments is not the way to go.

甚是思念 2024-12-22 15:44:40

解引用的 set 迭代器是一个 const int&。因此,如果没有 const,则无法将其作为 int& 参数传递。尝试简单的 (int i)(const int& i)

这确实不是您可以使用 auto 的地方之一。我认为 auto 仅适用于带有初始值设定项的声明或作为尾随返回类型的占位符。

A dereferenced set<int> iterator is a const int&. So you can't pass it as an int& parameter without the const. Try either plain (int i) or (const int& i).

And that's really not one of the places you're allowed to use auto. I think auto only works in a declaration with initializer or as a placeholder for a trailing return type.

落花随流水 2024-12-22 15:44:40

您应该能够迭代一组。但是,请注意,由于集合中的元素也是其键,因此无法修改。当您不打算修改元素时,更改代码以采用 const 引用,并使用 cbegin/cend 代替,无论是否是集合。

You should be able to iterate over a set. However, note that since the element in a set its also its key, it cannot be modified. Change your code to take a const reference, and use cbegin/cend instead, regardless of whether is a set or not when you are not going to modify the elements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文