- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在为这个 SparseGraph
类制作这个 const_iterator 时遇到了一些严重的问题
稀疏图类:
出于本文的意图和目的,SparseGraph
可以被视为边列表(或 vector 的 vector )的列表(这通常称为邻接列表)。 const_iterator
然后遍历列表列表中的每条边。
考虑:
template <typename NodeType, typename EdgeType>
class SparseGraph
{
public:
//...
using EdgeList = std::vector<EdgeType>;
using AdjacencyList = std::vector<EdgeList>;
//...
private:
//...
AdjacencyList m_adj_list;
//...
}
const_iterator(嵌套类)的初始尝试
//----SparseGraph
template <typename NodeType, typename EdgeType>
class SparseGraph
{
public:
class const_iterator; //nested
//...
}
//----SparseGraph::const_iterator
template <typename NodeType, typename EdgeType>
class SparseGraph<NodeType, EdgeType>::const_iterator
{
private:
using NodeIterator = typename SparseGraph<NodeType, EdgeType>::AdjacencyList::const_iterator;
using EdgeIterator = typename SparseGraph<NodeType, EdgeType>::EdgeList::const_iterator;
//this is used to iterate through each edge list corresponding to each node
NodeIterator m_node_it;
//this is used to iterate through each edge in each edge list.
EdgeIterator m_edge_it;
public:
const_iterator(const NodeIterator& node_it, const EdgeIterator& edge_it)
: m_node_it{node_it}, m_edge_it{edge_it} {}
const_iterator& operator++(int)
{
//TODO
return *this;
}
//...
人们可能会注意到,operator++()
给出了“非静态引用”错误:
error: invalid use of non-static data member 'SparseGraph::m_adj_list'
来自:
//...
if(m_node_it == m_adj_list.end()) { //<--here,
//loop back around to the beginning
m_node_it = m_adj_list.begin(); //<--here,
}
m_edge_it = m_node_it.begin();//<--and here.
//...
const_iterator(友元类)的初始尝试
现在我们有一些类似的东西:
//----SparseGraph
template <typename NodeType, typename EdgeType>
class SparseGraph
{
public:
friend class const_iterator; //friend
//as before...
}
//----SparseGraph::const_iterator-------------------------------------------------------------------------------------------------------------
template <typename NodeType, typename EdgeType>
class const_iterator
{
private:
using NodeIterator = typename SparseGraph<NodeType, EdgeType>::AdjacencyList::const_iterator;
using EdgeIterator = typename SparseGraph<NodeType, EdgeType>::EdgeList::const_iterator;
const SparseGraph<NodeType, EdgeType>& m_graph;
NodeIterator m_node_it;
EdgeIterator m_edge_it;
public:
const_iterator(const SparseGraph<NodeType, EdgeType>& graph,
const NodeIterator& node_it,
const EdgeIterator& edge_it)
: m_graph{graph} {}
//...
然后给了我错误
error: 'const_iterator' does not name a type
对于
template <typename NodeType, typename EdgeType>
class SparseGraph
{
//...
public:
//...
const_iterator begin() const;
//...
}
和
error: need 'typename' before 'SparseGraph::const_iterator' because 'SparseGraph' is a dependent scope
对于
template <typename NodeType, typename EdgeType> typename
SparseGraph<NodeType, EdgeType>::const_iterator SparseGraph<NodeType, EdgeType>::begin() const
{
return const_iterator(*this, m_adj_list.begin(), m_adj_list.begin() >begin());
然后变为
error: no 'typename SparseGraph::const_iterator SparseGraph::begin() const' member function declared in class 'SparseGraph'
当我添加那个类型名称时。我怀疑如果我解决了第一个错误就会解决这个问题,但是我不知道问题出在哪里。此外,friend 类现在正在污染包含它的任何翻译单元的范围。
我的当前代码
#ifndef SPARSE_GRAPH_H
#define SPARSE_GRAPH_H
#include <iostream>
#include <vector>
enum
{
invalid_node_index=-1
};
template <typename NodeType, typename EdgeType>
class SparseGraph
{
public:
class const_iterator;
using Node = NodeType;
using Edge = EdgeType;
using NodeList = std::vector<Node>;
using EdgeList = std::vector<Edge>;
using AdjacencyList = std::vector<EdgeList>;
private:
//...
//Similarly to the NodeList, each node index is analogous
//to its index in this list. Each element of this list contains
//a sub-list of edges associated with a particular node.
//For example, the list at index 3 will contain all edges associated
//with the node with an index of 3. This is so we can have an O(1) lookup time.
AdjacencyList m_adj_list;
//...
public:
SparseGraph() {}
//...
const_iterator begin() const;
const_iterator end() const;
//...
};
//----SparseGraph::const_iterator-------------------------------------------
template <typename NodeType, typename EdgeType>
class const_iterator
{
private:
using NodeIterator = typename SparseGraph<NodeType, EdgeType>::AdjacencyList::const_iterator;
using EdgeIterator = typename SparseGraph<NodeType, EdgeType>::EdgeList::const_iterator;
NodeIterator m_node_it;
EdgeIterator m_edge_it;
const NodeIterator m_begin;
const NodeIterator m_end;
public:
const_iterator(NodeIterator node_it,
EdgeIterator edge_it,
NodeIterator begin,
NodeIterator end)
: m_node_it{node_it}, m_edge_it{edge_it}, m_begin{begin}, m_end{end} {}
const_iterator& operator++(int)
{
//are we at the end of a valid edge list?
if(m_node_it != end && m_edge_it == m_node_it->end()) {
//move to the next non-empty edge list or to the end of the adjacency list
while(m_node_it != end && m_node_it->empty()) {
m_node_it++;
}
if(m_node_it != end) {
m_edge_it = m_node_it->begin();
}
}
else {
m_edge_it++;
}
return *this;
}
const_iterator& operator--(int)
{
//TODO
return *this;
}
const typename SparseGraph<NodeType, EdgeType>::Edge& operator*() const
{
return *m_edge_it;
}
const typename SparseGraph<NodeType, EdgeType>::Edge* operator->() const
{
return &(*m_edge_it);
}
bool operator==(const const_iterator& other) const
{
return m_node_it == other.m_node_it &&
m_edge_it == other.m_edge_it;
}
bool operator!=(const const_iterator& other) const
{
return !(*this == other);
}
};
//----SPARSE_GRAPH----------------------------------------------------------
//----PUBLIC FUNCTIONS------------------------------------------------------
//----begin()
template <typename NodeType, typename EdgeType>
typename SparseGraph<NodeType, EdgeType>::const_iterator SparseGraph<NodeType, EdgeType>::begin() const
{
return const_iterator(m_adj_list.begin(),
m_adj_list.begin()->begin(),
m_adj_list.begin(),
m_adj_list.back().end());
}
//----end()
template <typename NodeType, typename EdgeType>
typename SparseGraph<NodeType, EdgeType>::const_iterator SparseGraph<NodeType, EdgeType>::end() const
{
return const_iterator(m_adj_list.end(),
m_adj_list.end()->end(),
m_adj_list.begin(),
m_adj_list.back().end());
}
#endif // SPARSE_GRAPH_H
我的问题是,我应该怎么做?我应该使用嵌套的 const_iterator 类还是 friend const_iterator 类,或者,哪种方式是标准的?我应该如何实现 const_iterator 来避免这些问题?总的来说,我正在寻找一个双向 const_iterator,它将遍历 AdjacencyList(列表的列表)中的每个边,而不允许更改所述 AdjacencyList。
我查看了该站点上与“const_pointer 实现”相关的其他帖子,甚至提到了 Stroustrup 的“C++ 编程语言”,但到目前为止,还没有任何内容让我深入了解如何正确实现与此类似的 const_iterator .
我对如何正确处理这个问题一点也不满意,因此非常感谢对任何事情(可能与手头的主要问题无关)的任何帮助。
最佳答案
你的原创
error: invalid use of non-static data member 'SparseGraph::m_adj_list'
表示在获取m_adj_list.begin()
的范围内没有SparseGraph
。你不需要调用它,只需将 SparseGraph::m_adj_list 的开始和结束存储在你的 const_iterator
template <typename NodeType, typename EdgeType>
class SparseGraph<NodeType, EdgeType>::const_iterator
{
private:
using NodeIterator = typename SparseGraph<NodeType, EdgeType>::AdjacencyList::const_iterator;
using EdgeIterator = typename SparseGraph<NodeType, EdgeType>::AdjacencyList::const_iterator;
const_iterator(NodeIterator node_it, EdgeIterator edge_it, NodeIterator adjacent_begin, NodeIterator adjacent_end) : m_node_it{node_it}, m_edge_it{edge_it}, m_adjacent_begin{adjacent_begin}, m_adjacent_end{adjacent_end} {}
const NodeIterator m_adjacent_begin;
const NodeIterator m_adjacent_end;
NodeIterator m_node_it;
EdgeIterator m_edge_it;
const_iterator& operator++(int)
{
//are we at the end of this edge list?
if(m_edge_it == m_node_it->end()) {
//move to the next node's edge list.
m_node_it++;
//are we past the last node's edge list?
if(m_node_it == m_adjacent_end) {
//loop back around to the beginning
m_node_it = m_adjacent_begin;
}
m_edge_it = m_node_it.begin();
}
else {
m_edge_it++;
}
return *this;
}
}
关于c++ - const_iterator : nested class or friend class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44039455/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!