C++ 包装容器,用于提供不同接口的容器
我想为stl容器创建通用“包装器”,类似于:C++ 包装容器,用于提供不同接口的容器,c++,c++11,containers,wrapper,variadic-templates,C++,C++11,Containers,Wrapper,Variadic Templates,我想为stl容器创建通用“包装器”,类似于: template<template <typename, typename...> class Container = std::vector > class ContainerWrapper{ add(); size(); find(); resize(); sort(); /**/ } 模板 集装箱装卸工{ 添加(); 大小(); 查找(); 调整大小(); 排序(); /**/ } +迭代器
template<template <typename, typename...> class Container = std::vector >
class ContainerWrapper{
add();
size();
find();
resize();
sort();
/**/
}
模板
集装箱装卸工{
添加();
大小();
查找();
调整大小();
排序();
/**/
}
+迭代器。
我希望成员函数具有不同的实现,具体取决于容器提供的方法。是C++模板系统足以创建这个吗?这是可能的,只使用标准的(没有增强,没有干扰预处理器)
我知道如何用最困难的方法来完成——为每个stl容器编写模板专门化。但我希望它也能与其他容器一起使用,而且我正在寻找更通用的方法来实现它
还有,这里什么更好?继承自
容器
或将容器
作为组件?STL容器并不意味着要继承。这是讨论过的,但没有完成,因为这将是一个突破性的变化
所以使用构图是你最好的选择。不久前,我为我的一个项目开发了类似的东西 我提取了一个完整的工作示例(原始代码更复杂),以演示如何使用方法
addVal()
(调用push_back()
,push()
,insert()
或push_front()
)向包装容器添加值
如果我没记错的话,这个代码适用于std::vector
,std::set
,std::multiset
,std::unordered\u set
,std::unordered\u multiset
,std::deque
,std::queue
,std::priority\u queue
,std::forward\u list
和std::stack
其他容器(例如,std::array
)可能需要对cntWrp
进行不同的专门化
我不想解释每一行代码,但如果你有问题,我可以尝试回答(或者,如果你愿意,我可以给你我的github项目的链接)
榜样
#include <set>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <type_traits>
class emptyClass
{ };
template <typename ... Ts>
struct funcType;
template <typename T, typename ... Ts>
struct funcType<T, Ts...>
{ using type
= typename std::conditional<T::result,
typename T::type, typename funcType<Ts...>::type>::type; };
template <>
struct funcType<>
{ using type = emptyClass; };
#define methodCheck_1(meth) \
\
class helpMeth_1_##meth {}; \
\
template <typename T, typename A> \
struct isWithMethod_1_##meth \
{ \
template<typename U> \
static decltype(U().meth(A())) func (U*); \
\
template<typename U> \
static emptyClass func (...); \
\
static const bool result \
= ! std::is_same<emptyClass, \
decltype(func<T>(nullptr))>::value; \
\
using type = helpMeth_1_##meth; \
}
methodCheck_1(insert);
methodCheck_1(push);
methodCheck_1(push_back);
methodCheck_1(push_front);
template <typename>
class cntWrp;
template <template <typename ...> class C, typename X, typename ... Xs>
class cntWrp< C<X, Xs...> >
{
private:
using addModeType = typename funcType<
isWithMethod_1_push_back<C<X, Xs...>, X>,
isWithMethod_1_insert<C<X, Xs...>, X>,
isWithMethod_1_push<C<X, Xs...>, X>,
isWithMethod_1_push_front<C<X, Xs...>, X>>::type;
static constexpr addModeType addMode {};
void addVal (X const & x, helpMeth_1_push_back const)
{ val.push_back(x); }
void addVal (X const & x, helpMeth_1_push const)
{ val.push(x); }
void addVal (X const & x, helpMeth_1_insert const)
{ val.insert(x); }
void addVal (X const & x, helpMeth_1_push_front const)
{ val.push_front(x); }
void addVal (X const & x, emptyClass const)
{ throw std::runtime_error("cntWr<>::addVal without mode"); }
public:
C<X, Xs...> val {};
cntWrp ()
{ }
cntWrp (C<X, Xs...> const & v0) : val { v0 }
{ }
void addVal (X const & x)
{ addVal(x, addMode); }
};
int main ()
{
cntWrp<std::set<int>> csi;
csi.addVal(2);
csi.addVal(7);
csi.addVal(5);
std::cout << "set:" << std::endl;
for ( auto const elem : csi.val )
std::cout << elem << std::endl;
cntWrp<std::vector<int>> cvi;
cvi.addVal(2);
cvi.addVal(7);
cvi.addVal(5);
std::cout << "vector:" << std::endl;
for ( auto const elem : cvi.val )
std::cout << elem << std::endl;
}
#包括
#包括
#包括
#包括
#包括
类空循环类
{ };
模板
结构函数类型;
模板
结构函数类型
{使用类型
=typename std::conditional::type;};
模板
结构函数类型
{using type=emptyClass;};
#定义方法检查1(方法)\
\
类helpMeth_1_35;#meth{}\
\
模板\
结构是使用方法1方法的\
{ \
模板\
静态decltype(U().meth(A()))func(U*)\
\
模板\
静态空类函数(…)\
\
静态常数布尔结果\
=!std::is_same::value\
\
使用type=helpMeth_1_35;#meth\
}
方法检查1(插入);
方法检查1(推);
方法检查1(推回);
方法检查1(向前推);
模板
类cntWrp;
模板
类cntWrp
{
私人:
使用addModeType=typename funcType<
使用方法1推后,
Is使用方法\u 1\u插入,
使用方法1推动,
isWithMethod_1_push_front>::键入;
静态constexpr addModeType addMode{};
void addVal(X常量和X,helpMeth\u 1\u push\u back常量)
{val.push_back(x);}
void addVal(X常量和X,helpMeth_1_push常量)
{val.push(x);}
无效添加值(X常量和X,帮助方法插入常量)
{val.insert(x);}
无效添加值(X常量和X,帮助方法1推动前常量)
{val.push_front(x);}
无效添加值(X常量和X,空类常量)
{throw std::runtime_错误(“cntWr::addVal无模式”);}
公众:
C val{};
cntWrp()
{ }
cntWrp(C常数&v0):val{v0}
{ }
无效添加值(X常量和X)
{addVal(x,addMode);}
};
int main()
{
cntWrp-csi;
csi.addVal(2);
csi.addVal(7);
csi.addVal(5);
std::cout关于标准容器,它们不是为继承而设计的。因为每个containerRapper
都是不相关的类型,为什么要这样做?我的意思是,不是每个std容器都可以调整大小
。当传递std::set
时会发生什么情况,这如何使您的解决方案比只使用st>更好d::首先设置
?你是否沉迷于某个类型的成员?为什么不只是自由函数?比如排序(容器)
@FrançoisAndrieux作为我对答案的评论;它们不是设计为多态继承的。这是不对的,你将继承和多态性混为一谈。protected
是public
的超集,因此非多态继承是使用任何类的有效方式(除非标记为final
)。