Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Boost_Metaprogramming_Boost Mpl - Fatal编程技术网

C++ 如何从类型列表继承,然后调用继承成员列表中的成员?

C++ 如何从类型列表继承,然后调用继承成员列表中的成员?,c++,templates,boost,metaprogramming,boost-mpl,C++,Templates,Boost,Metaprogramming,Boost Mpl,我有一组具有以下结构的类: class U { public: explicit U(int) { ... } U() {...} Init(int) {...} }; 我需要能够将这些类中的一个或多个组成一个类X。伪代码: template<class TypeSequence> class X that derives publicly from all the classes in TypeSequence { X(int): all base

我有一组具有以下结构的类:

class U
{
public:
    explicit U(int) { ... }
    U() {...}
    Init(int) {...}
};
我需要能够将这些类中的一个或多个组成一个类X。伪代码:

template<class TypeSequence>
class X that derives publicly from all the classes in TypeSequence
{
    X(int): all bases are initialized with the integer passed 
    {}
    //if the above constructor is impossible, then the following will do as well:
    X(int)
    {
        Call Init on all bases and pass the given int to them.
    }
};
模板
从TypeSequence中的所有类公开派生的类X
{
X(int):所有基都用传递的整数初始化
{}
//如果无法使用上述构造函数,则以下操作也可以:
X(整数)
{
对所有基调用Init并将给定的int传递给它们。
}
};
我想我需要很多mpl,但我不是很擅长。我想做的事可行吗?一个代码示例就好了


我的错:忘了提到我不能使用C++11功能。我正在寻找MPL解决方案。

类似的解决方案应该可以:

template<class typeOne>
class X1 : public typeOne
{
    X(int b): typeOne(b)
    {}
};
template<class typeOne, class typeTwo>
class X2 : public typeOne, public typeTwo
{
    X(int b): typeOne(b), typeTwo(b)
    {}
};
template<class typeOne, class typeTwo, class TypeThree>
class X3 : public typeOne, public typeTwo, public typeThree
{
    X(int b): typeOne(b), typeTwo(b), typeThree(b)
    {}
};
模板
X1类:公共第一类
{
X(内部b):第一类(b)
{}
};
模板
X2类:公共类型一、公共类型二
{
X(内部b):第一类(b),第二类(b)
{}
};
模板
X3类:公共类型一、公共类型二、公共类型三
{
X(内部b):第一类(b)、第二类(b)、第三类(b)
{}
};
或者,如果您愿意为每个对象浪费几个字节,您可以使用占位符,只制作一个大的占位符。对于每个实例,每个未使用的基类型最多浪费一个字节

template<int>
class PlaceHolder { PlaceHolder(int){} };

template<
         class typeOne, 
         class typeTwo=PlaceHolder<2>, 
         class TypeThree=PlaceHolder<3>,
         class TypeFour=PlaceHolder<4>,
         class TypeFive=PlaceHolder<5>
        >
class X : 
         public typeOne, 
         public typeTwo, 
         public typeThree,
         public typeFour,
         public typeFive
{
    X(int b)
    : typeOne(b), 
    typeTwo(b), 
    typeThree(b),
    typeFour(b),
    typeFive(b)
    {}

    X(const X& b)
    : typeOne(b), 
    typeTwo(b), 
    typeThree(b),
    typeFour(b),
    typeFive(b)
    {}

    X& operator=(const X& b) {
        typeOne::operator=(b);
        typeTwo::operator=(b);
        typeThree::operator=(b);
        typeFour::operator=(b);
        typeFive::operator=(b);}
        return *this;
    }
};
模板
类占位符{占位符(int){};
模板<
第一类,
类typeTwo=占位符,
类TypeThree=占位符,
类TypeFour=占位符,
类别TypeFive=占位符
>
X类:
公共第一类,
公共第二类,
公共第三类,
公共第四类,
公共第五类
{
X(内部b)
:第一类(b),
第二类(b),
第三类(b),
第四类(b),
第五类(b)
{}
X(施工X&b)
:第一类(b),
第二类(b),
第三类(b),
第四类(b),
第五类(b)
{}
X和运算符=(常量X和b){
类型一:运算符=(b);
类型二:运算符=(b);
类型三:运算符=(b);
类型四:运算符=(b);
类型五::运算符=(b);}
归还*这个;
}
};
像这样的东西

template <typename ...BaseClasses>
class Aggregator : public BaseClasses...
{
public:
    Aggregator(int i) : BaseClasses(i)...
    {}

};
模板
类聚合器:公共基类。。。
{
公众:
聚合器(INTI):基类(i)。。。
{}
};
用法示例:

Aggregator<U, V, W> a(10);
Aggregator<U, V> b(15);
Aggregator<W> c(20);
#include <iostream>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/vector.hpp>

struct A
{
  A(int x) { std::cout << "A::A " << x << std::endl; }
};

struct B
{
  B(int x) { std::cout << "B::B " << x << std::endl; }
};

struct C
{
  C(int x) { std::cout << "C::C " << x << std::endl; }
};

int main()
{
  InheritFrom_IntConstructor< boost::mpl::vector<A, B, C> >(1);
}
聚合器a(10);
聚合器b(15);
聚合器c(20);

注意:它使用可变模板,因此需要C++11。

好的,Boost.MPL包含元函数
inherit
inherit\u linear
您可以将它们与
for\u each
组合,以获得第二个变量(使用init函数)。或者只使用
boost::mpl::fold
和自定义元函数:

struct Null_IntConstructor
{
  Null_IntConstructor(int) { }
};

struct InheritFrom_IntConstructor_Folder
{
  template<typename T1, typename T2>
  struct apply
  {
    struct type : T1, T2
    {
      type(int x) : T1(x), T2(x) { }
    };
  };
};

template<typename Bases>
struct InheritFrom_IntConstructor 
  : boost::mpl::fold<Bases, 
                     Null_IntConstructor,
                     InheritFrom_IntConstructor_Folder>::type
{
  InheritFrom_IntConstructor(int x) 
    : boost::mpl::fold<Bases, 
                       Null_IntConstructor,
                       InheritFrom_IntConstructor_Folder>::type(x) 
  { }
};
struct Null\u IntConstructor
{
Null_int构造函数(int){}
};
结构从\u IntConstructor\u文件夹继承
{
模板
结构应用
{
结构类型:T1、T2
{
类型(intx):T1(x),T2(x){}
};
};
};
模板
从构造函数继承的结构
:boost::mpl::fold::type
{
继承自_int构造函数(int x)
:boost::mpl::fold::type(x)
{ }
};
用法示例:

Aggregator<U, V, W> a(10);
Aggregator<U, V> b(15);
Aggregator<W> c(20);
#include <iostream>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/vector.hpp>

struct A
{
  A(int x) { std::cout << "A::A " << x << std::endl; }
};

struct B
{
  B(int x) { std::cout << "B::B " << x << std::endl; }
};

struct C
{
  C(int x) { std::cout << "C::C " << x << std::endl; }
};

int main()
{
  InheritFrom_IntConstructor< boost::mpl::vector<A, B, C> >(1);
}
#包括
#包括
#包括
结构A
{

A(intx){std::cout我没有使用Boost,我也不确定我的解决方案与您需要的有多接近。但我仍然在发布它:

template<typename typeseq>
struct X : typeseq::head, X<typename typeseq::tail>
{
   typedef typename typeseq::head base;
   typedef X<typename typeseq::tail> recursebase;
   X(int i) : base(i), recursebase(i) {}
   void init(int i) 
   {
       base::init(i);
       recursebase::init(i);
   }
};

template<>
struct X<null_type> 
{
   X(int i) {}
   void init(int i)  { } 
};
模板
结构X:typeseq::head,X
{
typedef typename typeseq::头部底座;
typedef X递归基;
X(inti):基(i),递归基(i){
void init(int i)
{
碱基::init(i);
递归基::init(i);
}
};
模板
结构X
{
X(int i){}
void init(int i){}
};
然后,测试代码:

typedef typelist<S,typelist<U>> typeseq;
X<typeseq> x(10);
x.init(100);
typedef类型列表typeseq;
X(10);
x、 init(100);

在线演示:

您不能使用具有不同模板参数编号的同一模板。请注意,更改了模板名称,并添加了一个仅使用一个名称的版本,但可能会浪费空间。我确实不喜欢您的解决方案,但我对它投了赞成票,因为您花时间试图帮助我。谢谢,我不喜欢我的解决方案或者。:D+1问得好。顺便问一下,你听说过mixin吗?也许,它可以在这里使用,或者是它的一个变体?我以前使用过,但我手头没有代码,现在也没有时间写完整的答案。如果到那时还没有人回答,我今晚会重新讨论这个问题。作为一个提示,我记得我制作了一个特殊的mixin使用两个
boost::mpl::vector
迭代器作为模板参数。U与TypeSequence有什么关系?@Nawaz:我认为mixin不适用。我不需要U类中派生类的信息。我需要一些类似于mpl::inherit_的东西,我只是无法理解语法。我也不知道如何初始化bases或call Init在其上绝对需要C++0x的可变模板功能。+1:这非常干净和简单。谢谢。不幸的是,我不能使用可变模板:(
BaseClasses(I)…
行得通吗?§14.5.3/5看起来行得通!太棒了!C++11表现力的好例子。我想把原来的问题推广到任意数量的任意类型构造函数参数。@Mooing Duck:实际上,对我来说,这是一个全新的参数,我没有真正检查标准,g++接受了它,我假设它是co更正:p@Begeoth:非常好用。我需要研究一下
fold
到底做了什么,但是非常感谢!@Armen:
mpl::fold
几乎和我在解决方案中做的一样。当我看到Begemoth的答案时,我也想到了这一点,我正要发布它。不过你比我的原始答案快多了纳尔斯。