Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 包装容器,用于提供不同接口的容器_C++_C++11_Containers_Wrapper_Variadic Templates - Fatal编程技术网

C++ 包装容器,用于提供不同接口的容器

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(); /**/ } 模板 集装箱装卸工{ 添加(); 大小(); 查找(); 调整大小(); 排序(); /**/ } +迭代器

我想为stl容器创建通用“包装器”,类似于:

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
)。