繁体   English   中英

C ++编译时类协定(即,模板元编程)

[英]C++ compile-time class contracts (ie, template-metaprogramming)

是否有任何定义编译时类合同的模式?

我的目标是:

  • 可维护性-在大型代码库中,指定和验证编译时协定非常有用,因此依赖项显而易见。
  • 质量错误消息-最好不要抱怨模板深处的一行代码不能调用方法,而最好还是要解决合同履行不足的问题。

就像是...

class StaticContract {
  static void Method();
};

class MeetsContract {
  static void Method();
};

// T must have all methods of StaticContract, or compile-time error.
template <class T /*   : StaticContract   */>
void DoSomething(T t);

我会接受:

  • 编译时执行合同的方式
  • 捕获/记录编译时合同的模式
  • {静态方法,成员方法,typedef等的子集的解决方案
  • 重新定义我的问题陈述的解决方案
  • 最佳实践

在这一点上,我的首选方法是借用Yakk的can_apply元函数:

namespace details {
    template <class...>
    using void_t = void;    

    template <template <class...> class Z, class, class...>
    struct can_apply : std::false_type {};

    template <template <class...> class Z, class...Ts>
    struct can_apply<Z, void_t<Z<Ts...>>, Ts...> : std::true_type{};
}

template <template <class...> class Z, class...Ts>
using can_apply = details::can_apply<Z, void, Ts...>;

将其粘贴在安全的地方。 然后,我们可以将类型的合同定义为我们期望有效的表达式。 在这种情况下,我们需要一个非const命名成员函数Method

template <class T>
using StaticContract = decltype(std::declval<T&>().Method());

所以我们只需要它:

template <class T>
void DoSomething(T ) {
    static_assert(can_apply<StaticContract, T>::value, "!");
}

合同也可以任意复杂。 也许您也需要T可以复制分配和增加:

template <class T>
using StaticContract = decltype(
    std::declval<T&>().Method(),
    std::declval<T&>() = std::declval<T const&>(),
    ++std::declval<T&>()
    );

如果选择该方法而不是static_assert方法,那么这自然也可以实现SFINAE。

这个技巧似乎提供了一个面包屑(从在编译时检测typedef(模板元编程)开始

template<typename T>
struct void_ { typedef void type; };

template<typename T, typename = void>
struct Foo {};

template<typename T>
struct Foo <T, typename void_<typename T::const_iterator>::type> {
      void do_stuff(){ ... }
};

嗯,如何将其编织成可行的样式?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM