2011-10-18 57 views
1

我想在C++中编写通用包装器。这是我到目前为止已经写的:通用包装C++

//primary template 
template<typename T> 
class function 
{ 
}; 
//partially specialized template 

template<typename T, typename U, typename V> 
class wrapper<T(U,V)> 
{ 
private: 
    //typedef pointer to function 
    typedef T (*pfn)(U,V); 
    pfn f; 

public: 

    wrapper(pfn func):f(func) 
    { 
    }; 

    T operator()(U a, V b) 
    { 
    return f(a,b); 
    } 
}; 

可使用实例化,例如:

wrapper<double(double, double)> someWrapper(&someFunction); 

我在想,如果有人能在以下方面指出我在正确的方向如何修改包装模板以便能够以下列方式实例化:

wrapper<double(double, double)> somewrapper(&someClass, &someClass::someFunction) 
wrapper<double(someClass*, double)> somewrapper(&someClass::someFunction) 

我会很感激这方面的帮助。

+5

'std :: function'有什么问题? –

+0

Boost已经在Boost.Function中有此功能:http://www.boost.org/doc/libs/1_47_0/doc/html/function.html – Dani

+0

http://loki-lib.sourceforge.net/ –

回答

2

改为使用std::function,或者如果您的编译器还没有TR1,则使用Boost实现。这就是说,这是你正在寻找指针成员函数特:

template<typename T, typename C, typename U, typename V> 
class wrapper<T (C::*)(U,V)> 
{ 
private: 
    //typedef pointer to member-function 
    typedef T (C::*pfn)(U,V); 
    pfn f; 

public: 

    wrapper(pfn func):f(func) 
    { 
    }; 

    T operator()(C c, U a, V b) 
    { 
    return (c.*f)(a,b); 
    } 
}; 

及其实例化这样的:

wrapper< double(someClass::*)(double, double) > somewrapper; 

你给我的第一个实例是不可能的,但它需要一个庞大的类型擦除的ammount得到它的工作,因为类的类型不能从构造函数参数推导出来。

wrapper<double(double, double)> somewrapper(&someClass, &someClass::someFunction) 

第二个可能会工作,稍微修改我的示例代码,假设您只想使用指向成员函数的实例化它。

wrapper<double(someClass*, double)> somewrapper(&someClass::someFunction) 

假设你想要一个包装的定义是对于用兼容参数的自由和成员函数可用,你又需要某种类型的擦除,使其工作。实施Boost.Function实际使用不同的技术来避免virtual调用。

+0

感谢您的回复。我编写了一个类似于你的类实现的实现,其中类类型作为模板参数传递,但正如你所说,我现在正在查看是否可以编写单个包装来涵盖所有这些场景。在我看来,这样做不是微不足道的!我会研究类型擦除,我不知道它。 – Omar

2

如果你将此作为一种编程和学习练习,那很好,但有很多可行的替代方案存在并经过彻底测试。如果使用C++ 11,则可以使用std::function,否则有boost::functionboost::bind

现在假设这是一个学习练习,您将需要为每个不同参数和返回值创建包装版本。您还需要涵盖函数是类成员的情况,并且您可能还想在处理Functor类时处理这种情况。

只要说这是很多工作,很多角落案例,只是为了复制已经存在的东西。

+0

感谢您的回答。是的,你可能已经制定出来了,这对我来说是一个学习练习。所以我会看看这些实现,看看它们是如何工作的。 – Omar