CRTP'ed 容器
CRTP'ed Containers
我正在一些模板编程中咬牙切齿,我对此非常陌生。我要实现的是几个包含 STL 容器的 CRTP 类。让我们class A{};
作为(编译时(基类的示例,class B{};
和class C{};
在编译时按照 CRTP 样式"派生"自该基类。
现在,B
和C
都将包含容器。出于示例的目的,请分别将其设为std::vector
和std::set
。现在,我想通过一个begin()
和一个公开前向迭代器的end()
函数来公开这些迭代器。但是,我不想公开 B
和 C
内部的确切容器是什么,我想为 A
定义这些函数,以便在调用时使用正确的 B
和 C
函数。
这可能吗?现在我的计划是有一个Iterator
的内部类,用于B
以及C
,它将包含(向量或集合,视情况而定(的实际迭代器,并将调用委托给它。但是,这似乎是很多复制的胶水代码,我怀疑有更好的选择。
我有几个问题:
-
如何在
A
、B
和C
中声明内链,以便它与 CRTP 很好地配合使用。我需要复制它A
、B
和C
吗?它可以在A
中是一个空类,我用专门的实现B
和C
屏蔽它们吗? -
如何以更少的胶水和更少的重复来公开迭代器?
我不想创建与 boost 等外部库的依赖项,只想坚持使用 std。所以我必须自己实现我需要的任何额外内容。感谢您的所有帮助。
也通过 CRTP 公开迭代器:
template <typename T, typename Iter, typename ConstIter>
struct Base
{
Iter begin() { return static_cast<T*>(this)->begin(); }
Iter end() { return static_cast<T*>(this)->end(); }
ConstIter begin() const { return static_cast<const T*>(this)->begin(); }
ConstIter end() const { return static_cast<const T*>(this)->end(); }
};
struct B : Base<B, std::vector<int>::iterator, std::vector<int>::const_iterator>
{
std::vector<int>::iterator begin() { return container.begin(); }
...
private:
std::vector<int> container;
};
如果要公开更多类型,则将 traits 类作为模板参数传递给 Base
:
template <typename T, typename Traits>
struct Base
{
typename Traits::iterator begin() { ... }
...
};
// For this purpose, vector<int> makes a perfect traits class !
struct B : Base<B, std::vector<int> >
{
std::vector<int>::iterator begin() { ... }
...
};
// Here is an example function taking Base as argument
template <typename T, typename Traits>
void foo(const Base<T, Traits>& x)
{
typename Traits::iterator i = x.begin();
...
}
如果我理解你的意思,你正在寻找这样的东西。请注意,我做了一些简单的构造函数只是为了说明它的工作原理。另外,你的class A
是我的class TWrapperBase
,B
- TWrapperB
,C
- TWrapperC
。另一件事,对于这个特定示例,您实际上并不需要有两个派生类,但我假设您的类B
和C
显着不同,以证明您的程序中的合理性。
编辑:忘记在循环中增加 lIterSet。
#include <vector>
#include <set>
#include <iostream>
template< typename PType, typename PContainer >
class TWrapperBase
{
public:
typedef PType TType;
typedef PContainer TContainer;
typedef typename TContainer::iterator TIterator;
protected:
TContainer mContainer;
public:
TWrapperBase( const TContainer& pOriginal ) :
mContainer( pOriginal )
{
}
TIterator begin( void )
{
return mContainer.begin();
}
TIterator end( void )
{
return mContainer.end();
}
};
template< typename PType, class PContainer = std::vector< PType > >
class TWrapperB : public TWrapperBase< PType, PContainer >
{
public:
TWrapperB( const TContainer& pOriginal ) :
TWrapperBase( pOriginal )
{
}
};
template< typename PType, class PContainer = std::set< PType > >
class TWrapperC : public TWrapperBase< PType, PContainer >
{
public:
TWrapperC( const TContainer& pOriginal ) :
TWrapperBase( pOriginal )
{
}
};
int main( void )
{
int lInit[] =
{
1, 2, 3
};
std::vector< int > lVec( lInit, lInit + 3 );
std::set< int > lSet( lInit, lInit + 3 );
TWrapperB< int > lB( lVec );
TWrapperC< int > lC( lSet );
std::vector< int >::iterator lIterVec = lB.begin();
std::set< int >::iterator lIterSet = lC.begin();
while( lIterVec < lB.end() )
{
std::cout << "vector: " << *lIterVec << " / set: " << *lIterSet << std::endl;
lIterVec++;
lIterSet++;
}
return 0;
}
- 在提升multi_index容器中,是否定义了"default index"?
- 用于访问容器<T>数据成员的正确 API
- Eigen如何在容器循环中干净地附加矩阵
- 模板专用化(按容器):value_type
- 关联容器的下界复杂性:成员函数与非成员函数
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- 在STL容器中使用模板类
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 检查函数返回类型是否与STL容器类型值相同
- STL算法函数在多个一维容器上的使用
- 如何将带有自定义对象的容器从C++传递到QML
- 在没有未定义行为的情况下实现类似std::vector的容器
- 将 BASE 派生类存储在同一容器中
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 在C++中迭代 2D 容器的最干净方法
- 将线程中的数据存储到全局容器的最佳方法?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 使用带有C++对象和标准库容器的插件系统
- 使用 std::index_sequence 初始化具有固定大小数组成员的 POD 结构容器
- CRTP'ed 容器