- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个虚拟容器“ISequence”,用作数组或列表上容器实现的模板。我已经为 Array 和 List 容器实现了一个迭代器。我想要做的是创建一个虚拟 IIterator 类,这样我就可以创建使用迭代器并接受 ISequence 作为参数的算法。我的目标是免于实现。
我尝试在没有方法的情况下向 ISequence 添加虚拟 IIterator 类,并且它继承了 std::iterator 但这没有用
ISequence 类:
template <typename T>
class ISequence {
protected:
int length; //length of sequence
public:
virtual int getLength() const = 0; //get length of sequence
virtual bool getIsEmpty() const = 0; //check if empty
public:
virtual T get(int index) const = 0; //get item based on index
virtual T getFirst() const = 0; //get first item
virtual T getLast() const = 0; //get last item
virtual ISequence<T>* getSubSequence(int startIndex, int endIndex) const = 0;
virtual void append(T item) = 0; //add item to the end
virtual void prepend(T item) = 0; //add item to the beginning
virtual void insertAt(int index, T item) = 0; //insert item at a specific point
virtual void remove(T item) = 0; //remove specific item
virtual void replace(int index, T item) = 0; //replace an item
};
带迭代器的数组:
template <typename T>
class ArraySequence: public ISequence<T> {
private:
T* data;
public:
ArraySequence();
ArraySequence(ISequence<T>* sequence);
ArraySequence(int n, int leftLimit, int rightLimit);
ArraySequence<T>& operator=(const ArraySequence<T>& sequence);
~ArraySequence();
public:
virtual int getLength() const override;
virtual bool getIsEmpty() const override;
public:
virtual T get(int index) const override;
virtual T getFirst() const override;
virtual T getLast() const override;
virtual ArraySequence<T>* getSubSequence(int startIndex, int endIndex) const override;
virtual void append(T item) override;
virtual void prepend(T item) override;
virtual void insertAt(int index, T item) override;
virtual void remove(T item) override;
virtual void replace(int index, T item) override;
private:
class MyIterator: public std::iterator<std::random_access_iterator_tag, T> {
friend class ArraySequence;
private:
T* pos;
MyIterator(T* pos);
public:
MyIterator(const MyIterator &it);
~MyIterator();
public:
typename MyIterator::reference operator*() const;
typename MyIterator::pointer operator->() const;
typename MyIterator::reference operator[](const typename MyIterator::difference_type& n) const;
typename MyIterator::difference_type operator-(const MyIterator& it) const;
MyIterator operator++(int);
MyIterator& operator++();
MyIterator operator--(int);
MyIterator& operator--();
MyIterator operator+(const typename MyIterator::difference_type& n) const;
MyIterator& operator+=(const typename MyIterator::difference_type& n);
MyIterator operator-(const typename MyIterator::difference_type& n) const;
MyIterator& operator-=(const typename MyIterator::difference_type& n);
bool operator!=(const MyIterator& it) const;
bool operator==(const MyIterator& it) const;
bool operator<(const MyIterator& it) const;
bool operator>(const MyIterator& it) const;
bool operator<=(const MyIterator& it) const;
bool operator>=(const MyIterator& it) const;
};
public:
typedef MyIterator iterator;
typedef MyIterator const const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
};
我的抽象 IIterator 代码(作为 ISequence 的补充):
protected:
class IIterator: public std::iterator<std::random_access_iterator_tag, T> { //virtual Iterator class
};
public:
typedef IIterator iterator;
typedef IIterator const const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
然后我通过Array中的MyIterator继承
通过我的尝试,当我运行简单的 forrange 循环时,我得到了“二进制表达式的无效操作数(‘ISequence::IIterator’和‘ISequence::IIterator’)”错误消息。
最佳答案
您要实现的概念在 C# 中相当基础。也许 C++ 中不存在这些是有充分理由的?是的!
您正在尝试使用 C++ 实现 .Net 库。 这不是一个好主意,因为该库的设计迎合了 C# 和 CLR(或他们现在所说的任何东西)的局限性。 C# 在编译时对类型的处理要少得多,而且它没有像 C++ 那样的编译时泛型类型替换系统。通过不使用 C++ 提供的功能,您正在重新发明轮子并编写看起来非常单一的代码。而且它可能会比需要的慢,因为迭代器上的虚拟方法调用很容易被经常调用,它们的开销显示出来。如果可以的话,编译器会去虚拟化一些调用,但这不是可以依赖的东西。
概括一点; 默认情况下,在 C++ 中直接使用 .Net 生态系统中的大多数习语都是错误的,除非另有证明。
在 C++ 中,“接口(interface)”的概念不依赖于虚拟方法,而是依赖于概念——即类型约束。在 C# 中没有办法实现这一点,通常在 CLR 中也没有,设计不支持它。在 C++ 中,只要使用的具体类型符合调用者要求的约束(例如可迭代),编译器就会处理其余的事情。习惯上,您可以使用 ranges 传递容器或迭代器,所有接受这些的代码都应该是通用的:容器或迭代器的类型应该是一个模板参数,并且迭代器不应该被强制为相同的类型——这在旧版本中确实是一个库设计错误C++ 库。
因此,C++ 的美妙之处在于您不必定义任何接口(interface)。在 C++20 中,您可以使用概念来约束类型,但除此之外,它很简单——比在 C# 中简单得多。范围的想法是让对象的行为“像”容器,即您可以使用 range-for 对它们进行迭代,但它们不一定是容器——它们可能只是在容器上表达一系列元素的一种方式,甚至动态生成。
如果您正在考虑这样做以支持将代码从 C# 移植到 C++,那么只需忘记对 ISequence
等的需求。只需使用泛型类型参数,如果需要,可以选择使用概念约束它们您正在使用 C++20 编译器,并且您已准备就绪。就这么简单。容器可以是任何东西。即使是普通的“C”数组(不寒而栗 - 不要使用它们,请始终使用 std::array
!)。
假设我们有以下 C# 代码:
System.IO.TextWriter cout = Console.Out;
Action<System.Collections.IEnumerable> printValues = (values) =>
{
cout.WriteLine("printValues");
foreach (var v in values)
cout.Write($"{v} ");
cout.Write("\n");
};
var list_of_ints = new List<int>{1, 2, 3, 4, 5};
var vector_of_strings = new String[]{"a", "b", "c", "d"};
cout.WriteLine("* Entire containers");
printValues(list_of_ints);
printValues(vector_of_strings);
cout.WriteLine("\n* Subranges of containers");
printValues(list_of_ints.GetRange(1, list_of_ints.Count() - 1));
printValues(vector_of_strings.Take(vector_of_strings.Count() - 1));
输出:
* Entire containers
printValues
1 2 3 4 5
printValues
a b c d
* Subranges of containers
printValues
2 3 4 5
printValues
a b c
它在 C++ 中看起来并没有太大不同,只要您坚持使用 C++ 的惯用语并且不要尝试在 C++ 中重新实现 .Net:
#include <forward_list>
#include <iostream>
#include <string>
#include <vector>
// This will accept entire containers, as well as C++20 ranges.
template <class C> void printValues(const C &values) {
std::cout << __FUNCTION__ << " with container\n";
for (auto &v : values)
std::cout << v << " ";
std::cout << "\n";
}
// This is the more legacy way of doing it - to stay compatible with C++98 (shiver).
template <class I1, class I2> void printValues(I1 start, I2 end) {
std::cout << __FUNCTION__ << " with iterators\n";
for (; start != end; ++start)
std::cout << *start << " ";
std::cout << "\n";
}
int main() {
std::forward_list<int> list_of_ints{1,2,3,4,5};
std::vector<std::string> vector_of_strings{"a", "b", "c", "d"};
std::cout << "* Entire containers\n";
printValues(list_of_ints);
printValues(vector_of_strings);
std::cout << "\n* Subranges of containers\n";
printValues(std::next(list_of_ints.cbegin()), list_of_ints.cend());
printValues(vector_of_strings.cbegin(), std::prev(vector_of_strings.cend()));
}
输出:
* Entire containers
printValues with container
1 2 3 4 5
printValues with container
a b c d
* Subranges of containers
printValues with iterators
2 3 4 5
printValues with iterators
a b c
关于c++ - 是否可以创建虚拟迭代器类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58304719/
如果您有超过 1 个具有相同类名的(动态)文本框,并使用 jquery 循环遍历每个所述文本框,您是否可以假设每次选择文本框的顺序都是相同的? 示例: 文本框 1 值 = 1文本框 2 值 = 2文本
有人知道为什么这段代码无法顺利运行吗?它似乎不喜欢使用yield关键字进行迭代:我正在尝试从任何级别的列表或字典中挖掘所有数字(对列表特别感兴趣)。在第二次迭代中,它找到 [2,3] 但无法依次打印
我关于从 mysql 数据库导出数据并将其保存到 Excel 文件(多表)的创建脚本。我需要让细胞动态基因化。该脚本正确地显示了标题,但数据集为空。当我“回显”$value 变量时,我检查了数据是否存
我正在尝试在 Python 中运行模拟,由此我绘制了一个数组的随机游走图,给定了两个变量参数的设定水平。 但是,我遇到了一个问题,我不确定如何迭代以便生成 250 个不同的随机数以插入公式。例如我已经
我是学习 jquery 的新手,所以如果这是一个相对简单的问题,我深表歉意。我有一个 ID 为 ChartstoDisplay 的 asp.net 复选框列表。我正在尝试创建 jquery 来根据是否
我正在尝试根据在任意数量的部分中所做的选择找出生成有效案例列表的最佳方法。也许它不是真正的算法,而只是关于如何有效迭代的建议,但对我来说这似乎是一个算法问题。如果我错了,请纠正我。实现实际上是在 Ja
如果我使用 sr1 为 www.google.com 发送 DNSQR,我会收到几个 DNSRR(s) 作为回复,例如(使用 ans[DNSRR].show() 完成): ###[ DNS Resou
假设有这样一个实体类 @Entity public class User { ... public Collection followers; ... } 假设用户有成千上万的用户关注者。我想分页..
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Nested jQuery.each() - continue/break 这是我的代码: var steps =
我刚从 F# 开始,我想遍历字典,获取键和值。 所以在 C# 中,我会说: IDictionary resultSet = test.GetResults; foreach (DictionaryEn
我知道已经有很多关于如何迭代 ifstream 的答案,但没有一个真正帮助我找到解决方案。 我的问题是:我有一个包含多行数据的txt文件。 txt 文件的第一行告诉我其余数据是如何组成的。例如这是我的
我有 12 个情态动词。我想将每个模态的 .modal__content 高度与 viewport 高度 进行比较,并且如果特定模态 .modal__content 高度 vh addClass("c
在此JSFiddle (问题代码被注释掉)第一次单击空单元格会在隐藏输入中设置一个值,并将单元格的背景颜色设置为绿色。单击第二个空表格单元格会设置另一个隐藏输入的值,并将第二个单元格的背景颜色更改为红
这是一个非常具体的问题,我似乎找不到任何特别有帮助的内容。我有一个单链表(不是一个实现的链表,这是我能找到的全部),其中节点存储一个 Student 对象。每个 Student 对象都有变量,尽管我在
有没有办法迭代 IHTMLElementCollection? 比如 var e : IHTMLLinkElement; elementCollection:IHTMLElementCollect
我正在尝试用 Java 取得高分。基本上我想要一个 HashMap 来保存 double 值(因此索引从最高的 double 值开始,这样我更容易对高分进行排序),然后第二个值将是客户端对象,如下所示
我想在宏函数中运行 while/until 循环,并限制其最大迭代次数。我找到了如何在“通常”sas 中执行此操作: data dataset; do i=1 to 10 until(con
Iterator iterator = plugin.inreview.keySet().iterator(); while (iterator.hasNext()) { Player key
晚上好我有一个简单的问题,我警告你我是序言的新手。假设有三个相同大小的列表,每个列表仅包含 1、0 或 -1。我想验证对于所有 i,在三个列表的第 i 个元素中,只有一个非零。 此代码针对固定的 i
我在 scheme 中构建了一个递归函数,它将在某些输入上重复给定函数 f, n 次。 (define (recursive-repeated f n) (cond ((zero? n) iden
我是一名优秀的程序员,十分优秀!