我正在尝试用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)
我很感激你的帮助。
答案 0 :(得分:2)
如果您正在将此作为编程和学习练习,那么这很好,但有许多可行的替代方案存在并经过全面测试。如果使用C ++ 11,您可以使用std::function
,否则会boost::function
和boost::bind
。
现在假设这是一个学习练习,您需要为每个不同的参数和返回值创建包装器的版本。您还需要涵盖函数是类成员的情况,并且您可能还想在处理Functor类时处理该情况。
我只想说这是很多工作,很多极端情况,只是复制已经存在的东西。
答案 1 :(得分:2)
如果您的编译器还没有TR1,请使用std::function
或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;
你提供的第一个实例化并非不可能,但它需要大量的类型擦除才能使它工作,因为类型类型不能从构造函数参数中推断出来。
wrapper<double(double, double)> somewrapper( &someClass, &someClass::someFunction)
第二个可以使用,修改我的示例代码,假设你只想用指向成员函数的指针实例化它。
wrapper<double(someClass*, double)> somewrapper( &someClass::someFunction)
假设您希望单个包装器定义可用于具有兼容参数的free和member函数,则需要再次使用某种类型的擦除来使其工作。 Boost.Function
的实施实际上使用了不同的技术来避免virtual
次呼叫。