c++ - 当提供模板参数列表时,继承模板类列表

标签 c++ templates metaprogramming multiple-inheritance

我正在尝试编写一些元编程代码:

  • 继承自某个类 foo<c1, c2, c3, ...>结果继承自 key<c1>, key<c2>, key<c3>, ...
  • 最简单的方法并不完全有效,因为您不能多次从同一个空类继承。
  • 处理“...”部分不是很好(因为它是复制面食),但可以。

好的,下面是尝试:

template<char c0, typename THEN, typename ELSE>
struct char_if
{
    typename THEN type;
};
template<typename THEN, typename ELSE>
struct char_if<0, THEN, ELSE>
{
    typename ELSE type;
};
class emptyClass {};


template<char c> class key
{
    char getKey(){return c;}
};

template<char c0, char c1, char c2, char c3, char c4>
class inheritFromAll
{
    typename char_if<c0, key<c0>, emptyClass>::type valid;

    class inherit
        : valid
        , inheritFromAll<c1, c2, c3, c4, 0>::inherit
    {};
};

template<char c1, char c2, char c3, char c4>
class inheritFromAll<0, c1, c2, c3, c4>
{
    class inherit {};
};

template<char c0 = 0, char c1 = 0, char c2 = 0, char c3 = 0, char c4 = 0>
class whatINeedToDo
    : public inheritFromAll<c0, c1, c2, c3, c4>::inherit
{
    bool success(){return true;}

};

int main() 
{
    whatINeedToDo<'A', 'B', 'c', 'D'> experiment;
    return 0;
}

虽然我最初可以使用 Boost::Mpl 来做到这一点,但老实说我不知道​​如何做;我想不通你是怎么传递一个 list<...> 的并不总是明确知道 ...部分。

只是做:

template<> class key<0> {};

不起作用,因为如果我有多个 0参数,我尝试从同一事物继承两次。 (如果您能想到解决方法,那也行)。

我也没有尝试过宏,因为我认为我对它们的了解比我对元编程的了解还少,所以它们可能可以作为一种解决方案。

有什么想法吗?

编辑:我有一个不好的解决方案。我仍然想要一个元编程解决方案,用于学习,但不好的解决方案是这样的:

template<char c1, char c2, char c3> class inheritFromMany
    : public key<c1>
    , public key<c2>
    , public key<c3>
{

};
template<char c1, char c2> class inheritFromMany<c1, c2, 0>
    : key<c1>
    , key<c2>
    {

    };

Edit2:哇,但我忘记了一部分。我需要将一个变量传递给“键”的构造函数 - 在所有情况下都是一样的,但这是必要的。

Edit3:处理评论:

  • 我不希望用户多次提交相同的字符。如果他们这样做了,我只想从那个 key 继承一次——我的意思是,我想我没有提到它是因为你不能那样做?这就是为什么其他更简单的解决方案不起作用的原因?
  • 实际意义在于,key 是信号/槽( channel )行为的包装器。该 channel 保留了一个回调列表,实际上就是 virtual key<ch>::callback .因此,从键继承可以让您访问该键的 channel ,让(或使)您提供回调。 keyInput<ch1, ch2, ch3,...>然后是一个包装器,所以你不必 key<ch1>, key<ch2>, key<ch3>

最佳答案

无需说明您实际想要实现的目标,这主要是学术练习...但这是您如何使用 MPL 进行线性继承的一种方式:

template<class T> struct key {
    enum { value = T::value };
    char getKey() { return value; }
};

template<class Values> struct derivator 
    : mpl::inherit_linearly<
          Values
        , mpl::inherit< mpl::_1, key<mpl::_2> >
        >::type
{};

// usage:    
typedef mpl::vector_c<char, 1,2,3> values;
typedef derivator<values> generated;

// or:
derivator< mpl::vector_c<char, 1,2,3> > derived;

也许你可以在此基础上阐明你需要什么。

I need to pass a variable to the constructor of ''key'' - it's the same in all cases, but it's necessary.

您的意思是要通过继承链将参数传递给所有构造函数吗?然后看看this question的解决方案.


至于在可见界面中避免 mpl::vector_c,您可以使用之前的方法并通过仅在其中插入不等于零的值来在内部构建它:

template<char c, class S> struct push_char {
    typedef typename mpl::push_front<S, mpl::char_<c> >::type type;
};

template<class S> struct push_char<0, S> {
    typedef S type; // don't insert if char is 0
};

template<char c1=0, char c2=0, char c3=0>
struct char_vector { 
    // build the vector_c
    typedef 
        typename push_char<c1
      , typename push_char<c2
      , typename push_char<c3
      , mpl::vector_c<char> 
      >::type>::type>::type
    type; 
};

template<char c1=0, char c2=0, char c3=0> 
struct derivator 
    : mpl::inherit_linearly<
          typename char_vector<c1,c2,c3>::type
        , mpl::inherit< mpl::_1, key<mpl::_2> >
        >::type
{};

关于c++ - 当提供模板参数列表时,继承模板类列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2338049/

相关文章:

C++风格: Stroustrup' s placement of pointer asterisks

c++ - 如何防止为未实现方法的对象生成模板

c++ - 使用模板检查结构中的字段,启用函数,如果失败则给出错误消息?

C++ 类型特征

ruby - 在 rspec 测试中实现前置/后置条件的更好方法

C++ 计算器不适用于 * 运算符

c++ - 如何使用 C++ 成员函数作为 C 框架的回调函数

c++ - 如何处理原子性情况

c++ - 基类的未定义模板参数

c++ - 如何编写适用于 32 位和 64 位的 std::bitset 模板