- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在大学学习 OOP 类(class)(C++ 是基础语言)。我的任务是实现自己的链表模板容器类。我几乎完全做到了,但遇到了问题。已知STL提供iterator
和 const_iterator
通过列表进行迭代的类。它们具有几乎相同的实现,主要区别在于 iterator 的方法返回引用,而 const_iterator 的方法——常量引用。我关注了https://stackoverflow.com/a/3582733/2108548并创建了单独的模板类 ListIterator
.然后我用 typedef
声明类(class) Iterator
和 ConstIterator
类内List
.
我有这样的东西:
template<typename T>
class ListNode
{
public:
ListNode(T *node_value = nullptr, ListNode *node_prev = nullptr, ListNode *node_next = nullptr):
value(node_value), prev(node_prev), next(node_next) { }
T *value;
ListNode *prev, *next;
};
template<typename T>
class ListIterator
{
typedef ListNode<T> Node;
public:
ListIterator();
ListIterator(Node *node);
ListIterator(ListIterator const &other);
ListIterator &operator++();
// ...
Node *i;
};
template<typename T>
class List: public Container
{
typedef ListIterator<T> Iterator;
typedef ListIterator<T const> ConstIterator;
// ...
Iterator begin() const
{
return Iterator(m_first->next);
}
ConstIterator const_begin() const
{
return ConstIterator(begin());
}
// ...
};
一切都很好,直到我决定制作“复制构造函数”Iterator
-> ConstIterator
.所以我需要获取 ListIterator<T>
的构造函数方法(其中 T
是数据类名称)并创建新对象类型 ListIterator<T const>
.但实际上ConstIterator
的构造函数得到 T const
作为模板参数,所以我需要删除 const
对于构造函数的参数。我找到标题 type_traits
这是做什么的。所以我写了“复制构造函数”: typedef 类型名 std::remove_cv::type NoConstT; ListIterator(ListIterator const &other);
但是没用!请求 const_begin() 后出现此错误:
List<int> list1;
list1 << 1 << 2 << 3;
int i = *list1.const_begin();
error: 'ListIterator<T>::ListIterator(const ListIterator<typename std::remove_cv<_Tp>::type>&) [with T = int; typename std::remove_cv<_Tp>::type = int]' cannot be overloaded with 'ListIterator<T>::ListIterator(const ListIterator<T>&) [with T = int; ListIterator<T> = ListIterator<int>]'
但这还不是全部。为了实现我的目标必须转换 ListNode<T>
至 ListNode<T const>
以及。但我还有一个问题:每个列表节点都包含指向上一个和下一个节点的指针,如果我尝试在节点的构造函数中初始化它们,我将得到递归。当然,我可以创建处理所有 ListNode<T>
转换的函数。节点到 ListNode<T const>
通过迭代它们。但我不喜欢这个解决方案:它有巨大的开销!
我问过老师这个问题。好几分钟他都不懂,明白了就说:“初等!” — “但我坚持了 3-4 个小时!” — “如果是这样,扔掉 const 迭代器并在没有它们的情况下完成列表容器。我需要时间来理解你的代码”(正如你所看到的,我认为我的代码非常简单)。据我所知,他不知道这个问题的答案。但我真的很想知道怎么做!我该如何解决这个问题?
很抱歉犯了很多错误 — 我的母语不是英语。
最佳答案
你确实可以使用 <type_traits>
,只是不像你描述的那样。一种方法是始终声明来自同一类型的构造函数,并使用 enable_if
有条件地从非常量声明。仅当模板参数确实不是常量时。并且节点应该始终是非常量的,你可以用 remove_const
来做到这一点.
#include <type_traits>
template<typename T>
class ListNode
{
//...
};
template<typename T>
class ListIterator
{
typedef ListNode<typename std::remove_const<T>::type> Node;
public:
ListIterator() {}
ListIterator(Node*) {}
ListIterator(ListIterator const&) {}
template <typename U>
ListIterator(ListIterator<U> const&, typename std::enable_if<!std::is_const<U>()>::type* = nullptr) {}
};
template<typename T>
class List
{
public:
typedef ListIterator<T> Iterator;
typedef ListIterator<T const> ConstIterator;
// ...
Iterator begin()
{
return Iterator(/*...*/);
}
ConstIterator const_begin() const
{
return ConstIterator(/*...*/);
}
// ...
};
int main() {
List<int> list;
List<int>::ConstIterator ci = list.const_begin();
List<int>::Iterator i = list.begin();
ci = i; // works fine as expected
i = ci; // fails as expected
i = i; // works fine as expected
ci = ci; // works fine as expected
return 0;
}
关于c++ - 将基于自定义模板的迭代器类的对象转换为 const_iterator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15816391/
我刚开始使用 Dagger 2,想知道与我目前用来实现依赖注入(inject)的技术相比,它有什么优势。 目前,为了实现 DI,我创建了一个具有两种风格的项目:mock 和 prod。在这些风格中,我
我是一名优秀的程序员,十分优秀!