![](/img/trans.png)
[英]Building data structures at compile time with template-metaprogramming, constexpr or macros
[英]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);
我会接受:
在这一点上,我的首选方法是借用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.