2014-10-28 40 views
0

我正在为用整数表示句柄的C库编写一个C++包装器。有一些开放函数(Aopen,Bopen,Copen,Dopen,Eopen,...)和相应的关闭函数(Aclose,Bclose,Cclose,Dclose,Eclose,...)。我目前有包装类实现基本的RAII,但我有一些代码重复,因为每个包装只有在它打开和关闭例程调用。为了摆脱这种重复,我正在考虑对每个例程(例如Atype,Bytpe等)的值定义的枚举进行模板化,然后在编译时选择正确的打开和关闭函数。它想是这样的:在枚举值上的模板值选择句柄打开/关闭

TypeWrapper<AType> wrapped_a(...) 
TypeWrapper<BType> wrapped_b(...) 
... 

这是一个合理的做法,有没有更简单的方法,还是有一个名称为这种类型的构造?

谢谢!

+0

你可以只从一个公共基类继承,只覆盖开启和关闭功能。这样你就可以摆脱代码重复。 – 2014-10-28 18:57:13

+0

的确,那肯定会奏效。虽然在编译时似乎有足够的信息来做到这一点,但应该可以避免vtable调用。绝对过早的优化 - 我想我更多地要求知识的好奇心。 – 2014-10-28 19:06:17

+0

我曾经写过[answer here](http://stackoverflow.com/a/21712722/1413395),这可能会指向正确的方向。你也应该用更完整的样本改善你的问题。 – 2014-10-28 19:07:02

回答

2

你可以做一些类似如下:

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>;

Live example

2

你在找什么是模板专业化。

基本上,这是通过在枚举值上模拟您的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; 
}