我阅读了有关基于范围的循环的文档for:
如果范围类型具有名为 begin 的成员和名为 end 的成员,则使用成员解释。无论成员是类型、数据成员、函数还是枚举器,也无论其可访问性如何,都会执行此操作。
class meow { enum { begin = 1, end = 2}; /* rest of class */ };因此,即使存在命名空间范围的开始/结束函数,类似的类也不能与基于范围的 for 循环一起使用。
我不明白这一段。成员解释做了什么才能禁止示例类与基于范围的 for 循环一起使用?
这个问题的原因是我见过这样的代码:
\nauto fun(std::vector<Foo>&& v) {\n std::vector<Bar> w;\n for (auto&& e : v /* not an rvalue, but keep reading */) {\n w.push_back(std::move(e));\n }\n // do stuff with w\n}\nRun Code Online (Sandbox Code Playgroud)\n静态分析工具将其标记为错误,因为转发引用e正在被std::moved 而不是被std::forwarded。
另一方面,v肯定绑定到纯右值或 xvalue(客户端知道是或想要fun将其视为临时值的东西),因为它的类型是右值引用。是的,我看到函数的主体没有以任何方式声明v在for,但这只会让我认为我应该改变
for (auto&& e : v)到for (auto&& e : std::move(v)),auto&&,E&&假设类似using E = std::decay_t<decltype(v)>::value_type;。据我了解,第一点没有达到我预期的效果。事实上,std::move就目前而言,似乎没有任何影响for …
我正在尝试迭代通过 a 访问的 astd::vector<X>中包含的a 。与我的预期相反,如果我首先将其存储到副本中与直接迭代它,则行为会有所不同:struct Tstd::optional<T>std::optional<T>
#include <optional>
#include <string>
#include <vector>
// The rest is the same in both implementations
struct Object
{
std::string id;
std::vector<SomeStructType> items;
};
Object readDataFile() { /*....*/ return {}; }
bool dataFileExists() { /*....*/ return true; }
std::optional<Object> getData()
{
if (!dataFileExists()) {
return std::nullopt;
}
Object obj = readDataFile();
return obj;
}
int main()
{
// Implementation 1 - works
auto items = getData().value().items;
for (auto const& item …Run Code Online (Sandbox Code Playgroud) 免责声明:这更多是出于好奇,而不是缺乏其他解决方案!
是否可以在 C++ 中实现一个函数:
T() 具有某种合理生命周期的默认构造?我们的第一次尝试是:
template<typename T>
T& DefaultIfNullDangling(T* ptr) {
if (!ptr) {
return T(); // xxx warning C4172: returning address of local variable or temporary
} else {
return *ptr;
}
}
Run Code Online (Sandbox Code Playgroud)
第二次尝试是这样完成的:
template<typename T>
T& DefaultIfNull(T* ptr, T&& callSiteTemp = T()) {
if (!ptr) {
return callSiteTemp;
} else {
return *ptr;
}
}
Run Code Online (Sandbox Code Playgroud)
这消除了警告并在某种程度上延长了临时的生命周期,但我认为它仍然很容易出错。
背景:
整个过程是由如下所示的访问模式触发的:
if (pThing) {
for (auto& …Run Code Online (Sandbox Code Playgroud) 我需要一个公开 std::vector API 的一小部分的向量类。除了基于范围的之外,一切都有效。这里我尝试实现一个前向迭代器,但是它无法编译。
\n#include <vector>\n#include <iostream>\n\ntemplate <class T>\nclass OwningVector : private std::vector<T*> {\n using super = std::vector<T*>;\n\npublic:\n OwningVector() = default;\n ~OwningVector()\n {\n for (T* e : *this)\n delete e;\n super::clear();\n }\n OwningVector(const OwningVector& other)\n : super()\n {\n super::reserve(other.size());\n for (T* e : other)\n super::emplace_back(e->clone());\n }\n OwningVector& operator=(const OwningVector& other)\n {\n if (this == &other)\n return *this;\n OwningVector ret(other);\n swap(*this, ret);\n return *this;\n }\n\n void emplace_back(T* e) { super::emplace_back(e); }\n\n size_t size() const { return super::size(); }\n T* const& …Run Code Online (Sandbox Code Playgroud) 我想编写一个可以与参数一起使用的函数,否则该函数可能直接出现在基于范围的循环中:
template <typename Iterable>
void sayIt(const Iterable& stuff) {
for (const auto& e : stuff) {
cout << e << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于 stl 容器和其他类型,但不适用于大括号封闭的初始化程序:
std::vector<std::string> baz(2, "sorry");
sayIt(baz); // okay
sayIt({"foo", "bar"}); // not okay
Run Code Online (Sandbox Code Playgroud)
有没有办法让函数同时使用两者?
我在竞争性编程中遇到了初学者概念的问题
打印中的额外空间可能会导致错误的答案判断
我想迭代像地图或集合这样的容器,但最后一个值不应该有空格
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> st = {1,2,3};
for(auto x : st){
cout<<x<<" ";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
set<int> st = {1,2,3};
for(auto x = st.begin(); st!=end();x++){
if(x!=st.end()-2) cout<<x<<" ";
else cout<<x;
}
Run Code Online (Sandbox Code Playgroud) 我想根据某些条件从地图中删除一些元素:
#include <unordered_map>
#include <ranges>
#include <iostream>
int main() {
std::unordered_map<int, int> numbers = {{1,2}, {2,1}, {3,2}, {4,5}};
auto even = [](auto entry){return entry.second %2 == 0;};
for(auto& [key, val] : numbers | std::views::filter(even)) {
numbers.erase(val);
}
for(auto& [key, val] : numbers) {
std::cout << key << " " << val << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
但似乎我正在使基于范围的循环所需的迭代器无效:
4 5
3 2
1 2
Run Code Online (Sandbox Code Playgroud)
我知道如何使用迭代器显式地执行此操作,但是是否有一种基于范围的简洁方法来删除基于过滤器的元素?
我正在浏览标准算法库,遇到一个示例,该示例以我以前从未见过的方式使用基于范围的 for 循环: https: //en.cppreference.com/w/cpp/algorithm/is_heap
在给出的示例中,他们使用基于范围的 for 循环来迭代整数向量:
for (auto t{1U}; auto i : v)
std::cout << i << (std::has_single_bit(++t) ? " | " : " ");
Run Code Online (Sandbox Code Playgroud)
我熟悉最常用的基于范围的 for 循环。例如
for (const auto& elem : vector)
{
// do something with elem
}
Run Code Online (Sandbox Code Playgroud)
然而,我很困惑auto t{1U},我以前从未见过它,想知道它做了什么?
看起来它可能是一个临时范围表达式:
https://en.cppreference.com/w/cpp/language/range-for
但我仍然对t实际是什么以及为什么这里需要它感到困惑?
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
vector<int> a = {1, 2, 3, 4, 5};
for (auto &x : a)
cout << x << endl;
}
Run Code Online (Sandbox Code Playgroud)
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
vector<int> a = {1, 2, 3, 4, 5};
for (auto x : a)
cout << x << endl;
}
Run Code Online (Sandbox Code Playgroud)
上面的两个代码打印相同的值(1、2、3、4、5)。但是初始化 &x 和 x 之间有什么不同吗?谢谢阅读!
c++ ×10
range-based-loop ×10
c++20 ×2
iterator ×2
algorithm ×1
auto ×1
c++11 ×1
for-loop ×1
reference ×1
rvalue ×1
set ×1
std-ranges ×1
stdoptional ×1
stl ×1
templates ×1