通用包装器 C++

发布于 2024-12-10 18:51:50 字数 842 浏览 0 评论 0原文

我正在尝试用 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)

我将不胜感激任何帮助。

I'm trying to write a generic wrapper in C++. Here is what I've written so far:

//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);
  }
};

Which can be instantiated using, for example:

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

I was wondering if somebody could point me in the right direction in terms of how to modify the wrapper template to be able to instantiate in the following ways as well:

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

I'd appreciate any help in this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

把昨日还给我 2024-12-17 18:51:50

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

您给出的第一个实例化并非不可能,但它需要大量的类型擦除才能使其工作,因为类类型无法从构造函数参数中推断出来。

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

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

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

假设您希望单个包装器定义可用于具有兼容参数的自由函数和成员函数,则您再次需要一些类型擦除才能使其工作。 Boost.Function 的实现实际上使用了不同的技术来避免虚拟 调用。

Use std::function instead, or the Boost implementation if your compiler does not have TR1 yet. That said, this is the specialization you are looking for pointer to member functions:

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

and its instantiate like this:

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

The first instantiation you gave is not impossible, but it needs a massive ammount of type erasure to get it to work, since the class type can't be deduced from the constructor argument.

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

The second one could be made to work, modifying my example code a bit, assuming you only want to instantiate it with pointer to member functions.

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

Assuming you want a single wrapper definition to be usable for both free and member functions with compatible arguments, you need again some type erasure to make it work. The implementation of Boost.Function actually uses a different technique to avoid virtual calls.

痴梦一场 2024-12-17 18:51:50

如果您将其作为编程和学习练习来进行,那就没问题,但是存在许多可行的替代方案并且经过了彻底的测试。如果使用 C++11,您可以使用 std::function,否则有 boost::functionboost::bind

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

可以说,这需要大量的工作,大量的极端情况,只是为了复制已经存在的东西。

If you're doing this as a programming and learning exercise, then that's fine, but there are many viable alternatives that exist and are thoroughly tested. If using C++11 you can use std::function, otherwise there's boost::function and boost::bind.

Now assuming this is a learning exercise, you will need to create versions of your wrapper for each number of different parameters and return values. You will also need to cover the cases where the function is a class member, and you might want to also deal with the case when you're dealing with a Functor class.

Suffice to say that this is a lot of work, lots of corner cases, just to duplicate something that already exists.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文