- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一些类,由于各种原因超出了本次讨论的范围,我无法修改(省略了不相关的实现细节):
class Foo { /* ... irrelevant public interface ... */ };
class Bar {
public:
Foo& get_foo(size_t index) { /* whatever */ }
size_t size_foo() { /* whatever */ }
};
(我正在处理许多类似的“Foo”和“Bar”类,它们都是从其他地方生成的代码和我不想子类化的东西,等等)
[编辑:澄清 - 尽管有许多类似的“Foo”和“Bar”类,但保证每个“外部”类都有 getter 和 size 方法。根据“内部”包含的类型,每个“外部”只有 getter 方法名称和返回类型不同。
所以,如果我有包含 Quux 实例的 Baz,就会有 Quux& Baz::get_quux(size_t index) 和 size_t Baz::size_quux()。]
考虑到 Bar 类的设计,您不能轻易地在 STL 算法(例如 for_each、find_if 等)中使用它,并且必须执行命令式循环而不是采用函数式方法(我更喜欢后者的原因也出来了本次讨论的范围):
Bar b;
size_t numFoo = b.size_foo();
for (int fooIdx = 0; fooIdx < numFoo; ++fooIdx) {
Foo& f = b.get_foo(fooIdx);
/* ... do stuff with 'f' ... */
}
所以...我从来没有创建过自定义迭代器,并且在阅读了关于 S.O. 的各种问题/答案之后。关于 iterator_traits 之类的,我想出了这个(目前半生不熟的)“解决方案”:
首先,自定义迭代器机制(注意:'function' 和 'bind' 的所有使用都来自 MSVC9 中的 std::tr1):
// Iterator mechanism...
template <typename TOuter, typename TInner>
class ContainerIterator : public std::iterator<std::input_iterator_tag, TInner> {
public:
typedef function<TInner& (size_t)> func_type;
ContainerIterator(const ContainerIterator& other) : mFunc(other.mFunc), mIndex(other.mIndex) {}
ContainerIterator& operator++() { ++mIndex; return *this; }
bool operator==(const ContainerIterator& other) {
return ((mFunc.target<TOuter>() == other.mFunc.target<TOuter>()) && (mIndex == other.mIndex));
}
bool operator!=(const ContainerIterator& other) { return !(*this == other); }
TInner& operator*() { return mFunc(mIndex); }
private:
template<typename TOuter, typename TInner>
friend class ContainerProxy;
ContainerIterator(func_type func, size_t index = 0) : mFunc(func), mIndex(index) {}
function<TInner& (size_t)> mFunc;
size_t mIndex;
};
接下来,我获取表示内部容器开始和结束的有效迭代器的机制:
// Proxy(?) to the outer class instance, providing a way to get begin() and end()
// iterators to the inner contained instances...
template <typename TOuter, typename TInner>
class ContainerProxy {
public:
typedef function<TInner& (size_t)> access_func_type;
typedef function<size_t ()> size_func_type;
typedef ContainerIterator<TOuter, TInner> iter_type;
ContainerProxy(access_func_type accessFunc, size_func_type sizeFunc) : mAccessFunc(accessFunc), mSizeFunc(sizeFunc) {}
iter_type begin() const {
size_t numItems = mSizeFunc();
if (0 == numItems) return end();
else return ContainerIterator<TOuter, TInner>(mAccessFunc, 0);
}
iter_type end() const {
size_t numItems = mSizeFunc();
return ContainerIterator<TOuter, TInner>(mAccessFunc, numItems);
}
private:
access_func_type mAccessFunc;
size_func_type mSizeFunc;
};
我可以按以下方式使用这些类:
// Sample function object for taking action on an LMX inner class instance yielded
// by iteration...
template <typename TInner>
class SomeTInnerFunctor {
public:
void operator()(const TInner& inner) {
/* ... whatever ... */
}
};
// Example of iterating over an outer class instance's inner container...
Bar b; /* assume populated which contained items ... */
ContainerProxy<Bar, Foo> bProxy(
bind(&Bar::get_foo, b, _1),
bind(&Bar::size_foo, b));
for_each(bProxy.begin(), bProxy.end(), SomeTInnerFunctor<Foo>());
根据经验,此解决方案可以正常运行(减去我在编辑上述内容时为简洁起见可能引入的任何复制/粘贴或拼写错误)。
最后,真正的问题是:
我不喜欢要求调用者使用 bind() 和 _1 占位符等。他们真正关心的是:外部类型、内部类型、外部类型获取内部实例的方法、外部类型获取计数内部实例的方法。
有没有办法以某种方式“隐藏”模板类主体中的绑定(bind)?我一直无法找到一种方法来分别为类型和内部方法分别提供模板参数...
谢谢!
大卫
最佳答案
您可以定义一个辅助模板结构来隐藏与 Foo 和 Bar 交互的实际机制。然后专门针对每个容器:
// incomplete general case
template <typename TOuter> struct LegacyContainerTraits;
// Specialization for 'Bar'
template <> struct LegacyContainerTraits<Bar>
{
// The inner type of 'Bar' is 'Foo'
typedef Foo inner_type;
static size_t get_size(Bar const& outer) {return outer.size_foo();}
static Foo& get_element(Bar const& outer, size_t index) {
return outer.get_foo(index);
}
};
// Specialization for Baz
template <> struct LegacyContainerTraits<Baz>
{
// The inner type of 'Baz' is 'Quux'
typedef Quux inner_type;
static size_t get_size(Baz const& outer) {return outer.size_quux();}
static Quux& get_element(Baz const& outer, size_t index) {
return outer.get_quux(index);
}
};
然后在 ContainerProxy
/ContainerIterator
中,您只需存储对容器的引用/拷贝并调用 LegacyContainerTraits 的适当特化,而不是存储和使用函数
。实际上,根本不需要 ContainerProxy
:
template <typename TOuter> class LegacyContainerIterator;
template <typename TOuter> LegacyContainerIterator<TOuter> begin(TOuter& );
template <typename TOuter> LegacyContainerIterator<TOuter> end(TOuter& );
template <typename TOuter>
class LegacyContainerIterator :
public std::iterator<std::random_access_iterator_tag,
typename LegacyContainerTraits<TOuter>::inner_type >
{
private:
...
friend LegacyContainerIterator<TOuter> begin<TOuter>(TOuter& );
friend LegacyContainerIterator<TOuter> end<TOuter>(TOuter& );
LegacyContainerIterator(TOuter& containerRef, size_t index) ... {};
...
public:
...
typename LegacyContainerTraits<TOuter>::inner_type& operator*() {
return LegacyContainerTraits<TOuter>
::get_element(mContainerRef, mIndex);
}
...
};
template <typename TOuter>
LegacyContainerIterator<TOuter> begin(TOuter& containerRef)
{
return LegacyContainerIterator<TOuter>(containerRef, 0);
}
template <typename TOuter>
LegacyContainerIterator<TOuter> end(TOuter& containerRef)
{
return LegacyContainerIterator<TOuter>(
containerRef,
LegacyContainerTraits<TOuter>::get_size(containerRef));
}
然后您可以在循环或算法中相当轻松地使用自由函数。即使在基于范围的 for 循环中:
Bar b=...;
for (auto it=begin(b); it!=end(b); ++it) {...}
for (auto f : b) {...}
std::for_each(begin(b), end(b), ...);
更充实的版本:http://ideone.com/JA9hC
关于c++ - 调整不可迭代容器以通过自定义模板化迭代器进行迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11165341/
如果您有超过 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
我是一名优秀的程序员,十分优秀!