C ++模板长类型列表

时间:2017-01-12 02:36:23

标签: c++ templates metaprogramming

我正在编写一个很大程度上依赖于类型参数化的C ++库。到目前为止,通过库参数化了四种类型。重要的是,并非每个类型组件都使用每种类型(即相关类的集合)。在下面的问题说明中,Component2独立于C类型至关重要。请注意,在下面的代码段中,可以从Component1的不兼容实例中获取Component3的类型兼容实例,因为D调用会删除类型build_something()。鉴于此要求,不可能对所有类模板使用相同的四种类型列表

template <typename A, typename B, typename C>
class Component1;

template <typename A, typename B, typename D>
class Component2;

template <typename A, typename B, typename C, typename D>
class Component3;

template <typename A, typename B, typename C>
class Component1 {
  void augment(const Component1&);
}

template <typename A, typename B, typename D>
class Component2 {
  template <typename D>
  Component3<A, B, C, D> process_something(const Component1<A, B, C>&, const D&);
}

template <typename A, typename B, typename C, typename D>
class Component3 {
  Component2<A, B, D> build_something(const B&) const;
}

// Choose some application-specific set of type substitions.
using a = ...;
using b = ...;
using c = ...;
using d1 = ...;
using d2 = ...;
d1 d1_instance;
d2 d2_instance;

// Make some objects.
Component3<a, b, c, d1> c3_first;
Component3<a, b, c, d2> c3_second;

// Get type-compatible objects below from type-incompatible objects above.
Component1<a, b, c> c1_first = c3_first.build_something(d1_instance);
Component1<a, b, c> c1_second = c3_second.build_something(d2_instance);
c1_first.augment(c1_second);

当然,重复所有这些类型列表变得不合适。我选择在类体外提供函数定义(即使类是模板)。此外,类型名称实际上是库实现中的整个单词,而不是单个字母。最后,此示例中的每个类都是实际库中一组类的替代。虽然根据这些方案之一进行了类型参数化,但是有许多类。我将在稍后添加更多方案。结果是代码,尤其是方法原型中的代码非常密集,难以维护甚至无法读取。

我正在寻找一个明确,有效且符合惯例的解决方案。我正在考虑以下解决方案,但我想知道是否有更清晰,更有效或更传统的解决方案。

我的候选解决方案是将相关类型分组到模板&#34;元类型&#34;,如下所示types1types2

template <typename A, typename B, typename C>
struct types1;

template <typename A, typename B, typename D>
struct types2;

class <typename types>
Component1;

class <typename types>
Component2;

然后可以从高级复合类型中提取较低级别的类型(尽管简单地将typdef放在元类型中也是有效的):

template <typename T>
struct get_A;

template <A, B, C>
struct get_A<type1<A, B, C>> {
  using type = A;
}

template <A, B, D>
struct get_A<type2<A, B, D>> {
  using type = A;
}

然后以下断言成立,因为get_AA组合中获取types1成分:

static_assert(std::is_same<int, typename get_A<types1<int, float, void>>::type>::value);

这个系统使得定义类内部结构变得更加简单,在统一不同方案的函数调用中增加了一些难度。一个严重的问题是,如果没有概念的语言级别约束(例如Concept Lite),则不可能简单地查看类模板定义并知道应该在types模板参数中应该做什么。当然还有其他问题使这种方法远非完美解决。

有更好的方法吗?

0 个答案:

没有答案