指向类模板成员的函数指针

Function pointer to class template member

本文关键字:函数 指针 成员      更新时间:2023-10-16

我有这个类:

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<T>::lessThan不存在的T,或者是一个类型或变量!

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

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

那么很明显,CompFun<int>CompFun<string>是不同的类型。不能创建泛型CompFun<T>变量。

但是,根据您要执行的操作,可能有一个好方法可以实现这一目标。

目前你必须做这样的事情:

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;

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

但是,您尝试声明已经是有效的 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 中的函数仍然是一个模板。