在枚举值上的模板值选择句柄打开/关闭
问题描述:
我正在为用整数表示句柄的C库编写一个C++包装器。有一些开放函数(Aopen,Bopen,Copen,Dopen,Eopen,...)和相应的关闭函数(Aclose,Bclose,Cclose,Dclose,Eclose,...)。我目前有包装类实现基本的RAII,但我有一些代码重复,因为每个包装只有在它打开和关闭例程调用。为了摆脱这种重复,我正在考虑对每个例程(例如Atype,Bytpe等)的值定义的枚举进行模板化,然后在编译时选择正确的打开和关闭函数。它想是这样的:在枚举值上的模板值选择句柄打开/关闭
TypeWrapper<AType> wrapped_a(...)
TypeWrapper<BType> wrapped_b(...)
...
这是一个合理的做法,有没有更简单的方法,还是有一个名称为这种类型的构造?
谢谢!
答
你可以做一些类似如下:
template <typename H, H Open(const char*), void Close(H)>
class Wrapper
{
public:
Wrapper(const char* file) : h(Open(file)) {}
~Wrapper() { Close(h); }
Wrapper(const Wrapper&) = delete;
Wrapper& operator = (const Wrapper&) = delete;
private:
H h;
};
然后using Wrapper_A = Wrapper<AHandle, AOpen, AClose>;
答
你在找什么是模板专业化。
基本上,这是通过在枚举值上模拟您的TypeWrapper类,然后为每个枚举值的打开/关闭调用提供专门的实现来完成的。
一个例子是胜过千言万语:live example
#include <iostream>
using namespace std;
enum Type {
AType = 0,
BType,
CType,
};
void AOpen() { std::cout << "A open." << std::endl; }
void BOpen() { std::cout << "B open." << std::endl; }
void COpen() { std::cout << "C open." << std::endl; }
template<Type T>
class TypeWrapper {
public:
void open();
void close();
};
template<>
void TypeWrapper<AType>::open() { AOpen(); }
template<>
void TypeWrapper<BType>::open() { BOpen(); }
template<>
void TypeWrapper<CType>::open() { COpen(); }
int main() {
TypeWrapper<AType> wrapped_a;
TypeWrapper<BType> wrapped_b;
wrapped_a.open();
wrapped_b.open();
return 0;
}
你可以只从一个公共基类继承,只覆盖开启和关闭功能。这样你就可以摆脱代码重复。 – 2014-10-28 18:57:13
的确,那肯定会奏效。虽然在编译时似乎有足够的信息来做到这一点,但应该可以避免vtable调用。绝对过早的优化 - 我想我更多地要求知识的好奇心。 – 2014-10-28 19:06:17
我曾经写过[answer here](http://stackoverflow.com/a/21712722/1413395),这可能会指向正确的方向。你也应该用更完整的样本改善你的问题。 – 2014-10-28 19:07:02