C++ 实现静态多态迭代器
我试图为模板化类型层次结构实现一个迭代器接口,它使用静态多态性来避免与转发到实现的解决方案相关的开销(除非可以编译掉) 我已经包括了我正在构建的类型和接口的一个简短演示,以及引用我遇到问题的内联注释 下面直接显示的层次结构的顶部是一个通用的C++ 实现静态多态迭代器,c++,c++11,C++,C++11,我试图为模板化类型层次结构实现一个迭代器接口,它使用静态多态性来避免与转发到实现的解决方案相关的开销(除非可以编译掉) 我已经包括了我正在构建的类型和接口的一个简短演示,以及引用我遇到问题的内联注释 下面直接显示的层次结构的顶部是一个通用的框。Convert方法可以通过对每个元素应用函数U Func(Box)返回一个新的Box template<typename T> class Box : public std::enable_shared_from_this<Box<
框
。Convert
方法可以通过对每个元素应用函数U Func(Box)
返回一个新的Box
template<typename T>
class Box : public std::enable_shared_from_this<Box<T>> {
public:
template <typename Func>
auto Convert(Func f) -> std::shared_ptr<Box<decltype(f(std::declval<T>()))>>;
// This is what I am trying to achieve using a statically
// compiled solution (e.g. without the use of a subclass
// returning an implementation pointer and using pimpl).
//
// const_iterator cbegin();
// const_iterator cend();
// Uses the sub-class cbegin/cend interface
std::vector<T> elements() {
std::vector<T> result;
std::copy(cbegin(), cend(), std::back_inserter(result);
return result;
}
};
最后,我们提供了一个包含具体向量的源框(实践中使用了其他源)
模板
类矢量箱:公共箱{
公众:
ConvertedBox(const std::vector&data):数据(data)
{}
//返回迭代器包装std::vector::const_迭代器
//常量迭代器cbegin(){
//返回数据\.cbegin();
//}
//常量迭代器cend(){…}
私人:
const typename std::向量和数据;
};
我尝试过各种各样的CRTP技巧,包括std::iterator
,但似乎无法将这些技巧组合起来。我想避免任何依赖于boost
的东西,但是假设C++11
中的任何东西都是OK
请注意,我只是在理解迭代器的情况时遇到了一些问题(我所包含的其他部分只是为了上下文)。您是否正在尝试编写一个类似的东西?@TomKnapen我所面临的挑战(我认为)与
boost::transform\u迭代器提供的东西是正交的。是的,ConvertBox
迭代器将通过重载运算符*
来应用函数,但我在本文中面临的更普遍的问题是如何跨类型层次结构提供一致的迭代器接口。如果cbegin()
和cend()
不是virtual
,您希望如何调用Box::elements()
中的子类boost::transform\u迭代器
?顺便说一句……使cbegin()
和cend()
虚拟可能会导致不好的事情发生,因为迭代器(从基类调用)的大小未知。@KyleKnoepfel很抱歉造成混淆。我知道这些接口不会是虚拟的。你想写点什么吗?@TomKnapen我面临的挑战(我认为)与boost::transform\u iterator
提供的东西是正交的。是的,ConvertBox
迭代器将通过重载运算符*
来应用函数,但我在本文中面临的更普遍的问题是如何跨类型层次结构提供一致的迭代器接口。如果cbegin()
和cend()
不是virtual
,您希望如何调用Box::elements()
中的子类boost::transform\u迭代器
?顺便说一句……使cbegin()
和cend()
虚拟可能会导致不好的事情发生,因为迭代器(从基类调用)的大小未知。@KyleKnoepfel很抱歉造成混淆。我知道这些接口不是虚拟的。
template<typename T, typename U, typename Func>
class ConvertedBox : public Box<T> {
public:
ConvertedBox(typename std::shared_ptr<Box<U>> box, Func func) :
box_(box), func_(func)
{}
// Return iterator wrapper around box_->cbegin()
//const_iterator cbegin()
//const_iterator cend()
private:
std::shared_ptr<Box<U>> box_;
Func func_;
};
template<typename T>
class VectorBox : public Box<T> {
public:
ConvertedBox(const std::vector<T>& data) : data_(data)
{}
// Return iterator wrapper std::vector<T>::const_iterator
//const_iterator cbegin() {
// return data_.cbegin();
//}
//const_iterator cend() { ... }
private:
const typename std::vector<T>& data_;
};