【问题标题】:Function pointer to class template member指向类模板成员的函数指针
【发布时间】:2015-04-18 02:59:27
【问题描述】:

我有这门课:

template <class T>
class list
{
    ...
    bool moreThan(T x, T y);
    bool lessThan(T x, T y);
    ...
};

我需要一个函数指针来更改我的类的行为,并在使用bool moreThan(T, T)bool lessThan(T, T) 之间切换。 所以我目前正在使用:

bool (list<int>::*foo)(int x, int y);
foo = &list<int>::lessThan;

并使用它:

(this->*foo)(x, y);

但我想要一个灵活的函数指针,以便我可以将它与我需要的任何T 一起使用,而不仅仅是int。那么有没有办法创建一个指向类模板成员的函数指针呢?比如:

template <class T>
bool (list<T>::*foo)(T x, T y); //this doesn't work

【问题讨论】:

  • 你会为此苦苦挣扎,因为list 的每个专业化可能对这些函数有不同的定义,甚至根本没有定义它们!

标签: c++ function pointers


【解决方案1】:

不,没有。指向成员的指针必须指向 something。类模板中的成员函数不是单个函数,而是一个函数族——每个函数都有不同的类型。甚至可能有一个 T 不存在 list&lt;T&gt;::lessThan ,或者是一个类型或变量!

如果我们为这样一个指向成员的指针创建一个别名:

template <typename T>
using CompFun = bool (list<T>::*)(T, T);

那么很明显CompFun&lt;int&gt;CompFun&lt;string&gt; 是不同的类型。您不能创建通用的 CompFun&lt;T&gt; 变量。

不过,根据您要执行的操作,可能有一个很好的方法来完成此操作。

【讨论】:

  • 我真希望你不要再使用这个模棱两可的术语“方法”了。
  • @LightningRacisinObrit 这有什么不明确的地方?
  • “方法”一词在 C++ 中没有明确定义。你的意思是暗示一个函数是一个成员吗?还是一种非静态的?还是一个虚拟的?还是一种纯粹的?为避免误解,请使用 标准化 术语:而不是 `method' 说 'function' 以那些相关的说明符为前缀。我们这里不是在做 Java。
  • @LightningRacisinObrit 我认为你不是this question 的粉丝?当然,“方法”在 C++ 中不是一个术语,但它是 OO 中的一个术语。我用它来表示作为类成员的函数(无论是否静态/虚拟/纯)。
  • 谢谢,只有一个问题:我是否需要用list&lt;int&gt;:: 声明函数指针才能知道它指向list 类的函数,对吗?但它为什么需要知道呢?
【解决方案2】:

目前你必须这样做:

template <typename T>
struct listComparePtr
{
    typedef bool (list<T>::*type)(T x, T y);
};

这样使用:

listComparePtr<int>::type foo = &list<int>::lessThan;
listComparePtr<double>::type foo2 = &list<double>::moreThan;

【讨论】:

    【解决方案3】:

    没有这样的单一函数指针,因为函数指针必须指向内存中的具体地址,但每个模板实例将是不同位置的不同函数。

    但是,您的声明尝试已经是有效的 C++14 变量模板。示例:http://coliru.stacked-crooked.com/a/b1f0904e0ee4d6ad

    同样,您可以将模板放入 C++14 通用 lambda:

    auto foo = []( auto && l, auto && x, auto && y )
                 { return l.moreThan( x, y ); };
    

    虽然 lambda 中的函数仍然是一个模板,但这样做的好处是为您提供了一个单一类型的句柄。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-13
      • 2012-07-05
      • 2011-12-09
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多