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);
我会接受:
- 在编译时执行合同的方法
- 捕获/记录编译时合同的模式
- {静态方法、成员方法、typedefs等}子集的解决方案
- 重新定义我的问题陈述的解决方案
- 最佳实践
在这一点上,我更喜欢的方法是借用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...>;
把它放在安全的地方。然后,我们可以将类型的契约定义为我们期望有效的表达式。在这种情况下,我们需要一个名为Method
:的非const
成员函数
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(){ ... }
};
嗯,如何把它编织成一个可行的图案?
相关文章:
- 为什么编程语言被编译为汇编程序而不是二进制?
- 以下编译时编程任务在C++中是可能的
- 所有的openMp c++编程都是使用在GPU上运行的-fopenmp编译的吗
- 为什么以下C++元编程代码在 N=100 时给出编译错误,但对于小 N 运行良好
- C++14 元编程:在编译/初始化时自动构建类型列表
- C++模板元编程:模板类型上的编译时条件运算符
- .NET:如何以编程方式确定是否已编译 .NET 应用程序
- C++/QT/ARM处理器的交叉编译/编程
- 如何以编程方式检测 DLL 是在 .NET 中编译为 32 位还是 64 位
- 使用 c# 以编程方式编译生成的.cpp文件
- C++编译时类契约(即模板元编程)
- 使用元编程在编译时初始化函数数组
- 如何以编程方式要求编译器在C++中编译文件
- Clang 无法使用模板元编程编译参数包扩展
- 编译错误 将模板编程与特征C++库结合使用
- 如何通过预处理器指令检查编程C++中是否需要预编译标头
- MFC 编程:编译时出错:线程代码中的错误
- 编译来自学习现代 3D 图形编程的失败代码 函数___tmainCRTStartup中引用未解析的外部符号_main
- C++编译的C代码与嵌入式编程中的纯C代码
- 链接器是否存在于所有编译的编程语言中