【问题标题】:Choosing base class template arguments based on derived class arguments根据派生类参数选择基类模板参数
【发布时间】:2014-02-04 22:40:37
【问题描述】:

希望下面的描述比较清楚:

我目前的设计具有类似于以下的类层次结构:

struct Base{
public:
    Base(Base* child) { children.add(child);}
protected:
    std::vector<Base*> children;
};

template< /* multiple typename T_n generated by Boost Preprocessor */ >
struct A : public Base{};

template <uint32_t N>
struct B : public Base{
public:
    B() : Base(new A< uint32_t, uint32_t, */ additional uint32_t arguments based on parameter N */ >() ){}    
};

我需要将 N + 1 个 uint32_t 类型的参数传递给 A 的构造函数的问题。

如上所述,我在这个类层次结构的一部分中使用了 Boost Preprocessor。我意识到这可能是现在解决我的问题的可能解决方案之一。然而,我的偏好是找到一种可能更好的方法(我发现 Boost Preproccesor 很难使用——肯定是由于我缺乏经验,我觉得它很挑剔,而且代码难以阅读)。

我怀疑 MPL 可以在这里使用,但我不知道如何实现。

非常感谢任何建议和帮助。我并不是说上面的设计是最好的设计,并且也愿意接受有关如何修复的建议。话虽如此,我仍然希望有一个基于当前设计的解决方案,至少是为了自学 C++ 和 Boost。

提前致谢,

施穆尔

【问题讨论】:

  • 阅读 CRTP 习语。或者只是为接受 N 的基类创建一个 size_t 模板参数,对于基 ctor 使用 N size_ts 的元组。
  • 我对 CRTP 习语很熟悉,但不确定它在这里如何适用。问题不在于基类,而在于传递给 Base 的另一个派生类(装饰器模式)。确实,我同意 A 的设计(具有可变长度的类型列表)不是理想的,但是很多代码库都依赖它,我现在不愿意更改它。

标签: c++ templates boost template-meta-programming


【解决方案1】:

所以本质上您希望B&lt;3&gt; 派生自A&lt;int, int, int&gt;?可以安排:

template <typename> struct BImpl;    // no definition

template <typename ...Args> struct BImpl<std::tuple<Args...>> : A<Args...> {};

template <int N> using B = BImpl<typename IntMaker<N>::type>;

现在你只需要创建IntMaker,像这样:

template <int N, typename ...Args>
struct IntMaker<N, Args...> : IntMaker<N - 1, int, Args...> {};

template <typename ...Args>
struct IntMaker<0, Args...>
{
    using type = std::tuple<Args...>;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多