标签: range-based-loop

基于范围的 for 循环 (C++11 起) 中的成员解释是什么?

我阅读了有关基于范围的循环的文档for

如果范围类型具有名为 begin 的成员和名为 end 的成员,则使用成员解释。无论成员是类型、数据成员、函数还是枚举器,也无论其可访问性如何,都会执行此操作。class meow { enum { begin = 1, end = 2}; /* rest of class */ };因此,即使存在命名空间范围的开始/结束函数,类似的类也不能与基于范围的 for 循环一起使用。

我不明白这一段。成员解释做了什么才能禁止示例类与基于范围的 for 循环一起使用?

c++ c++11 range-based-loop

6
推荐指数
1
解决办法
101
查看次数

基于范围的 for 循环无法检测它是否在右值上循环是否存在技术原因?

这个问题的原因是我见过这样的代码:

\n
auto 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}\n
Run Code Online (Sandbox Code Playgroud)\n

静态分析工具将其标记为错误,因为转发引用e正在被std::moved 而不是被std::forwarded。

\n

另一方面,v肯定绑定到纯右值或 xvalue(客户端知道是或想要fun将其视为临时值的东西),因为它的类型是右值引用。是的,我看到函数的主体没有以任何方式声明vfor,但这只会让我认为我应该改变

\n
    \n
  • for (auto&& e : v)for (auto&& e : std::move(v))
  • \n
  • auto&&E&&假设类似using E = std::decay_t<decltype(v)>::value_type;
  • \n
\n

据我了解,第一点没有达到我预期的效果。事实上,std::move就目前而言,似乎没有任何影响for …

c++ rvalue language-lawyer move-semantics range-based-loop

5
推荐指数
1
解决办法
280
查看次数

为什么不能迭代直接通过 std::Optional&lt;T&gt;::value() 访问的容器?

我正在尝试迭代通过 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++ algorithm c++20 stdoptional range-based-loop

5
推荐指数
1
解决办法
116
查看次数

是否可以在 C++ 中实现 DefaultIfNull 函数?

免责声明:这更多是出于好奇,而不是缺乏其他解决方案!

是否可以在 C++ 中实现一个函数

  • 传递一个 T 类型的指针
  • 要么向 T 指向的对象返回一个类似引用的东西
  • 或者,如果指针为空,则将类似引用的事物返回到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)

c++ object-lifetime range-based-loop

4
推荐指数
2
解决办法
174
查看次数

如何使用私有 std::vector 基类编写前向迭代器

我需要一个公开 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)

c++ iterator range-based-loop

4
推荐指数
1
解决办法
257
查看次数

如何将大括号括起来的初始化列表传递给函数?

我想编写一个可以与参数一起使用的函数,否则该函数可能直接出现在基于范围的循环中:

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)

有没有办法让函数同时使用两者?

c++ templates stl list-initialization range-based-loop

3
推荐指数
1
解决办法
416
查看次数

不要使用迭代器打印最后一个值之后的空格

我在竞争性编程中遇到了初学者概念的问题
打印中的额外空间可能会导致错误的答案判断
我想迭代像地图或集合这样的容器,但最后一个值不应该有空格

#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)

c++ iterator for-loop set range-based-loop

3
推荐指数
1
解决办法
179
查看次数

在基于范围的循环中删除地图元素

我想根据某些条件从地图中删除一些元素:

#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)

我知道如何使用迭代器显式地执行此操作,但是是否有一种基于范围的简洁方法来删除基于过滤器的元素?

c++ unordered-map std-ranges range-based-loop

3
推荐指数
1
解决办法
292
查看次数

在 std::make_heap 示例中的以下基于范围的 for 循环中,自动“t{1U}”有何作用?

我正在浏览标准算法库,遇到一个示例,该示例以我以前从未见过的方式使用基于范围的 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实际是什么以及为什么这里需要它感到困惑?

c++ c++20 range-based-loop

3
推荐指数
1
解决办法
91
查看次数

for循环的两个代码有什么区别?

#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++ reference auto range-based-loop

2
推荐指数
1
解决办法
67
查看次数