C 模板功能在任何集合成员字段上迭代
C++ Template Function to Iterate Over any Collection Member Field
我正在尝试编写一个模板函数,该功能在某些结构集合中通过用户指定字段迭代。例如,我想编写以下C :
struct Example {
int a;
bool b;
};
template<std::function<Field& (Class)> GetField, typename Field, typename Class>
void myFunc(std::iterator<Class> begin, size_t const length) {
cout << length << endl;
for (size_t i{ 0 }; i < length; ++begin, ++i) {
Field const &field{ GetField(*begin) };
// Forward field to some other template function
anotherTemplateFunction<Field>(field);
}
}
void main() {
Example exArray[]{ {5, true}, {8, false} };
std::list<Example> exList{ exArray, exArray + _countof(exArray) }
// Examples of how I would like to call myFunc...
myFunc<Example::a>(exArray, _countof(exArray));
myFunc<Example::b>(exList.begin(), exList.size());
}
上述不起作用,但希望意图很明确。如何编写MyFunc模板方法以在每个迭代项目的某些字段上完成通用迭代?另外,如果有某种方式(在Boost或标准库中)直接通过exArray[i].a
创建迭代器,也可以接受。
我通常使用的是:
void main() {
std::array<Example, 2> exArray{ {5, true}, {8, false} };
std::list<Example> exList{ exArray.begin(), exArray.end() };
auto access_a = [](Example& e)->int&{ return e.a;};
auto access_b = [](Example& e)->bool&{ return e.b;};
myFunc(exArray.begin(), exArray.end(), access_a);
myFunc(exList.begin(), exList.end(), access_b);
}
template<class ForwardIt, class Accessor>
void myFunc(ForwardIt begin,ForwardIt end, Accessor accessor) {
cout << end - begin << endl;
for (auto it = begin; it != end; it++) {
// Forward field to some other template function
anotherTemplateFunction(accessor(*it));
}
}
请注意我如何使用std::array
而不是RAW C样式数组。如果您可以访问C 11编译器,则std::array
(或std::vector
)应始终优于原始C数组。ES.27
为了减少样板代码,请考虑使用一些序列化库来解决此"迭代在类字段上"问题,例如增强序列化或魔术。
如果您知道成员语法和喜欢的指针,这很简单。不幸的是,很少使用这种语言的深奥特征:
template <class T> void foo(T);
template <auto Field, class It>
auto myFunc(It begin, It end)
{
for (; begin != end; ++begin)
{
foo((*begin).*Field);
}
}
int main()
{
std::vector<Example> v{{5, true}, {8, false}};
myFunc<&Example::a>(v.begin(), v.end()); // will call foo<int>(5) , foo<int>(8)
myFunc<&Example::b>(v.begin(), v.end()); // will call foo<bool>(true) , foo<bool>(false)
}
对于template <auto Field
,您需要C 17。
对于C 11语法更详细:
template <class T, class F, F T::* Field, class It>
void myFunc(It begin, It end)
{ /* same */ }
int main()
{
std::vector<Example> v{{5, true}, {8, false}};
myFunc<Example, int, &Example::a>(v.begin(), v.end()); // will call foo<int>(5) , foo<int>(8)
myFunc<Example, bool, &Example::b>(v.begin(), v.end()); // will call foo<bool>(true) , foo<bool>(false)
}
对您的问题有些含量,但我不明白您为什么要与std::list
的初始化变得复杂。在C 中,您的第一个容器应为std::vector
。
也没有std::iterator
相关文章:
- C++:用户定义的类,以成员字段作为地址
- 用于基于成员字段或函数创建比较器的快捷方式
- uninit_member:非静态类成员字段 m_cJobState.bstatus 未在此构造函数中初始化,也不在其调
- 派生类中的成员字段别名(无访问器功能)
- 如何使用 Clang 查找所有成员字段读/写?
- C 模板功能在任何集合成员字段上迭代
- 一次启用 MANY 类的成员字段,具体取决于模板<T>
- 如何在C++的专用模板类中访问模板类成员字段
- 动态链接到 c++ 静态成员字段时符号查找失败
- std :: async在成员字段的成员功能上
- C++使用成员字段设置比较器
- C++11 是否重新初始化初始化的成员字段
- 将控件作为成员字段传递给使用新 connect() 调用的方法
- 构造以shared_ptr作为成员字段的类的正确语法是什么
- 成员字段的 getter 的常用做法是什么?
- c++:对于多重继承类的子类中的重复成员字段,什么是好的重构
- C++ -- 将元素添加到私有成员字段 std::vector
- 重写派生类中的成员字段
- 在C++类中使用指针作为成员字段是不是很傻
- 模板继承成员字段