- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
"接口(interface)-6ren"> "接口(interface)-我想要实现的目标可能很容易解释:考虑我有一个抽象类,我知道它将包含多个已知类型的对象。然而,保存这些对象的实际容器将在子类中实现。 在我的抽象基类中,我现在想提供一个接口(interface)来迭代这-6ren">
我想要实现的目标可能很容易解释:考虑我有一个抽象类,我知道它将包含多个已知类型的对象。然而,保存这些对象的实际容器将在子类中实现。
在我的抽象基类中,我现在想提供一个接口(interface)来迭代这些对象。鉴于我不知道(或者不想修复)容器的类型,我认为迭代器可能是我最好的选择。
此类的概念声明可能如下所示:
class MyClass {
public:
// Other interface methods, e.g. size()
virtual Iterable<MyObject> objects() = 0;
};
这里的目的是我将能够像这样迭代我的类的嵌套对象:
MyClass *class = new ImplementationOfClass();
for (const MyObject &obj : class->objects()) {
// Do stuff with obj
}
然而,我面临的问题是我似乎无法弄清楚
Iterable<MyObject>
应该定义。这个对象的关键属性是,在定义这个类时,我只能指定返回值是可迭代的(使用 STL 风格的迭代器),并且会产生类型为
MyObject
的对象。当使用的迭代器被取消引用时。
最佳答案
在@FrançoisAndrieux 的帮助和https://stackoverflow.com/a/4247445/3907364 的提示下,我能够想出解决我的问题的方法。
本质上,这个想法是创建一个迭代器包装器,它存储一个函数来获取给定类型的对象(如果给定索引)。然后该索引就是迭代的内容。
这样做的好处是迭代器接口(interface)是通过指定解除引用它应该返回的对象类型来修复的。多态性通过使成员函数objects()
发挥作用。 virtual
这样每个子类都可以自己构造迭代器,提供自定义函数指针。因此,只要有办法将索引映射到容器中的相应元素(无论使用哪个),这个技巧都是可用的。
请注意,您可以直接使用指针,例如std::vector<T>::at
或创建一个将返回相应元素的自定义函数。
这是迭代器的实现(可能会改进实现,但似乎可以完成工作):
template< typename T > struct iterator_impl {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T;
using pointer = T *;
using reference = T &;
using access_function_t = std::function< T &(std::size_t) >;
// regular Ctor
iterator_impl(std::size_t start, access_function_t &func, const void *id)
: m_index(start), m_func(func), m_id(id) {}
// function-move Ctor
iterator_impl(std::size_t start, access_function_t &&func, const void *id)
: m_index(start), m_func(func), m_id(id) {}
// copy Ctor
iterator_impl(const iterator_impl &) = default;
// move ctor
iterator_impl(iterator_impl &&other) {
std::swap(m_index, other.m_index);
m_func = std::move(other.m_func);
std::swap(m_id, other.m_id);
}
// copy-assignment
iterator_impl &operator=(const iterator_impl &other) = default;
// prefix-increment
iterator_impl &operator++() {
++m_index;
return *this;
}
// postfix-increment
iterator_impl operator++(int) {
iterator_impl old = *this;
++(*this);
return old;
}
bool operator==(const iterator_impl &other) { return m_index == other.m_index && m_id == other.m_id; }
bool operator!=(const iterator_impl &other) { return !(*this == other); }
T &operator*() { return m_func(m_index); }
T *operator->() { return &m_func(m_index); };
protected:
std::size_t m_index = 0;
access_function_t m_func;
const void *m_id = nullptr;
};
请注意,我必须介绍
m_id
成员变量作为正确比较迭代器的一种手段(
std::function
无法使用
==
进行比较)。它的意思是例如包含元素的容器的地址。它的唯一目的是确保恰好具有相同索引但在完全不同的集合上迭代的 2 个迭代器不被视为相等。
Iterable<T>
的实现。 :
template< typename T > struct Iterable {
using iterator = iterator_impl< T >;
using const_iterator = iterator_impl< const std::remove_const_t< T > >;
Iterable(std::size_t start, std::size_t end, typename iterator_impl< T >::access_function_t &func, const void *id)
: m_begin(start, func, id), m_end(end, func, id) {}
iterator begin() { return m_begin; }
iterator end() { return m_end; }
const_iterator begin() const { return m_begin; }
const_iterator end() const { return m_end; }
const_iterator cbegin() const { return m_begin; }
const_iterator cend() const { return m_end; }
protected:
iterator m_begin;
iterator m_end;
};
关于C++: "Iterable<T>"接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67335987/
我对这个错误很困惑: Cannot implicitly convert type 'System.Func [c:\Program Files (x86)\Reference Assemblies\
考虑这段代码: pub trait Hello { fn hello(&self); } impl Hello for Any { fn hello(&self) {
问题很简单。是否可以构造这样一个类型 T,对于它下面的两个变量声明会产生不同的结果? T t1 = {}; T t2{}; 我已经研究 cppreference 和标准一个多小时了,我了解以下内容:
Intellij idea 给我这个错误:“Compare (T, T) in Comparator cannot be applied to (T, T)” 对于以下代码: public class
任何人都可以告诉我 : n\t\t\t\t\n\t\t\t 在以下来自和 dwr 服务的响应中的含义和用途是什么. \r\n\t\t\t \r\n\t\t\t
让 T 成为一个 C++ 类。 下面三个指令在行为上有什么区别吗? T a; T a(); T a = T(); T 为不带参数的构造函数提供了显式定义这一事实是否对问题有任何改变? 后续问题:如果
Rust中的智能指针是什么 智能指针(smart pointers)是一类数据结构,是拥有数据所有权和额外功能的指针。是指针的进一步发展 指针(pointer)是一个包含内存地
比如我有一个 vector vector > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8
我有一个来自 .xls 电子表格的数据框,我打印了 print(df.columns.values) 列,输出包含一个名为:Poll Responses\n\t\t\t\t\t。 我查看了 Excel
This question already has answers here: What are good reasons for choosing invariance in an API like
指针类型作为类型前缀与在类型前加斜杠作为后缀有什么区别。斜线到底是什么意思? 最佳答案 语法 T/~ 和 T/& 基本上已被弃用(我什至不确定编译器是否仍然接受它)。在向新向量方案过渡的初始阶段,[T
我正在尝试找到一种方法来获取模板参数的基类。 考虑以下类: template class Foo { public: Foo(){}; ~Foo(){};
这是一个让我感到困惑的小问题。我不知道如何描述它,所以只看下面的代码: struct B { B() {} B(B&) { std::cout ::value #include
为什么有 T::T(T&) 而 T::T(const T&) 更适合 copy ? (大概是用来实现move语义的???) 原始描述(被melpomene证明是错误的): 在C++11中,支持了一种新
在 Java 7 中使用 eclipse 4.2 并尝试实现 List 接口(interface)的以下方法时,我收到了警告。 public T[] toArray(T[] a) { ret
假设有三个函数: def foo[T](a:T, b:T): T = a def test1 = foo(1, "2") def test2 = foo(List(), ListBuffer()) 虽
我对柯里化(Currying)和非柯里化(Currying)泛型函数之间类型检查的差异有点困惑: scala> def x[T](a: T, b: T) = (a == b) x: [T](a: T,
考虑一个类A,我如何编写一个具有与相同行为的模板 A& pretty(A& x) { /* make x pretty */ return x; } A pretty(A&& x) {
Eclipse 表示由于泛型类型橡皮擦,类型参数不允许使用 instanceof 操作。 我同意在运行时不会保留任何类型信息。但是请考虑以下类的通用声明: class SomeClass{ T
在 C++14 中: 对于任何整数或枚举类型 T 以及对于任何表达式 expr: 有没有区别: struct S { T t { expr }; }; 和 struct S { T t = { exp
我是一名优秀的程序员,十分优秀!