我上过这堂课:
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
答案 0 :(得分:2)
不,没有。指向成员的指针必须指向某事。类模板中的成员函数不是单个函数,它是一个函数族 - 每个函数都有不同的类型。甚至可能存在T
list<T>::lessThan
不存在的template <typename T>
using CompFun = bool (list<T>::*)(T, T);
,或者是类型或变量!
如果我们为一个这样的成员指向别名:
CompFun<int>
然后很明显CompFun<string>
和CompFun<T>
是不同的类型。您无法创建通用{{1}}变量。
根据您尝试做的事情,可能有一个很好的方法来实现这一目标。
答案 1 :(得分: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;
答案 2 :(得分:0)
没有这样的单个函数指针,因为函数指针必须指向内存中的具体地址,但每个模板实例在不同的位置都是不同的函数。
但是,您对声明的尝试已经是有效的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中的函数仍然是一个模板。