我在Raspberry Pi 3B +上运行带有-std = c ++ 2a -Wall- -Wextra -pedantic的g ++ v8.2。我试图更好地了解自定义容器的基于范围的循环。
下面您将看到一个实现自定义类的类,该类具有基于的范围。很好然而。我在执行工作时还有其他一些具体问题。
我也已经检查this和其他人。但是这些都没有回答我的问题。
代码如下:
#include <iostream>
struct LinkedList // Simplest linked list
{
int k;
LinkedList *next;
};
// For test pruposes: Build manually linked list as globals
LinkedList aa3{3,nullptr}; LinkedList aa2{2,&aa3}; LinkedList aa1{1,&aa2};
class Example
{
public:
Example &begin (void) { linkedList = linkedListStartAddress; return *this;}
int end (void) { return 0; }
LinkedList &operator * (void) { return *linkedList; }
void operator ++ (void) { linkedList = linkedList->next; }
bool operator != (const int&) { return (linkedList != nullptr);}
protected:
LinkedList *linkedListStartAddress {&aa1}; // Global initialisation for test purposes
LinkedList *linkedList{&aa1}; // Global initialisation for test purposes
};
int main(void)
{
Example example;
for (auto l : example)
{
std::cout << l.k << '\n';
}
return 0;
}
好的,这可行。
循环的一般定义是:
{
auto && __range = range_expression ;
auto __begin = begin_expr;
auto __end = end_expr
for (;__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
这很难理解。以后不使用__range和range_expression。在这种情况下,“自动”对我来说也很困难。我看不到类型。现在我的假设和问题。
如果您能对此有所了解,我会很高兴。 。
答案 0 :(得分:0)
解决方案的主要问题是,您试图以一种非标准的方式进行处理,这存在很多局限性,并且可能会使精通迭代器在STL中的工作原理的专家难以使用。
我将尝试以技术性较低的方式回答大多数问题,这应该有助于理解其在实践中的工作原理。
1)共享类型将导致一些问题,因为某些算法可能需要多个活动迭代器。另外,它不遵守SRP(单一责任原则),因此不是一个好的设计实践。
2)它只需要返回本质上类似于迭代器的行为。
3)或者,如果数据在内存中是连续的,也可能是一个指针。
4)通常,begin
函数按值返回迭代器。
5)通常,end
函数将迭代器返回到末尾。如果结尾不是真正的位置(例如,输入流或容器的最后一个值是哨兵),它也可能返回哨兵对象。
6)您可以将自己的typedef / aliases放在类中,并在适当时使用它们。
7)运算符*的返回值类型几乎总是与迭代器类型之一不同。
然后是一些评论/建议
LinkedList
是迭代器类型(或者您可以使用包装器)。sort
中的std::list
。constness
,因此如果将Example example;
替换为const Example example;
,将无法正常工作。begin
函数有副作用。void
放入空参数列表实际上是一种过时的方式来编写在C ++中不应再使用的代码。它仅在C语言中有用。enum
值)。否则,它将允许意外的比较像example != 25
那样进行编译(在这种情况下,可能会在k
的值为25时结束循环),从而使代码更难以理解。 std::forward_list
而不是重新发明轮子。LinkedList
,那么STL可能是有关如何正确定义迭代器的宝贵信息。