函数指针和继承
Posted
技术标签:
【中文标题】函数指针和继承【英文标题】:function pointer and inheritance 【发布时间】:2012-09-18 17:09:56 【问题描述】:我有一个通用函数,用于对 List 类中的一些对象进行排序。
这个函数工作得很好,但是当我想使用指向该类中成员函数的函数指针将该函数应用到一个类时,它不会构建。
函数是:
template <typename T1, typename T2, typename T3>
void DialogFaitListing::trie(T1 * list, T2 (T1::*fx)(quint16), T3 (T2::*crit)())
for(int i(0);i<list->count();i++)
for(int j(i);j<list->count();j++)
if((((list->*fx)(i)).*crit)() > (((list->*fx)(j)).*crit)())
list->swap(i,j);
其中list是包含对象列表的类,fx是访问对象的函数指针,crit是用于排序的对象比较函数。
当我使用这条线构建时:
trie(vend,&Vendeurs::getVend,&Vendeur::getNom);
我收到此错误:
dialogfaitlisting.cpp:459: erreur : no matching function for call to
'DialogFaitListing::trie(Vendeurs*&, Vendeur (Vendeurs::*)(quint16),
QString (Personne::*)())'
ps:对不起我的英语不好
【问题讨论】:
你是three star programmer吗?让事情变得更简单! 你需要提供一个更简单更完整的例子。例如,如果不查看您如何声明模板类,就不可能知道这里可能出现的所有错误。另外,trie 的实现在这里并不重要;它只会增加问题的噪音。尝试将您的代码减少到仍然产生错误的最小示例并发布整个结果(可能在单个 .cpp 文件中大约 10 行)。 【参考方案1】:&Vendeur::getNom
,尽管是可通过Vendeur
访问的成员,但似乎具有QString (Personne::*)()
类型。这使得T2
在模板参数推导过程中变得模棱两可:是Vendeur
还是Personne
?
创可贴的解决方法是让trie
的调用者承担显式转换为QString (Vendeur::*)()
的负担,从而导致以下调用:
trie(vend, &Vendeurs::getVend, static_cast<QString (Vendeur::*)()>(&Vendeur::getNom));
考虑到每次我们希望传递的crit
erion 来自基类时,我们都可能发现相同的错误,这非常冗长且不方便。
更好的解决方案是在T2
出现的两个位置之一上禁止模板参数推导。我认为为此选择第二个位置是有意义的:
template<typename T>
struct identity typedef T type; ;
template <typename T1, typename T2, typename T3>
void trie(T1 * list
, T2 (T1::*fx)(quint16)
, T3 (identity<T2>::type::*crit)());
那么在调用中T2
只能推导出为Vendeur
,而&Vendeur::getNom
会隐式转换为QString (Vendeur::*)()
。
【讨论】:
【参考方案2】:您似乎同时试图将T2
的第二个参数中的Vendeur
约束为trie
(因为Vendeur Vendeurs::getVend(quint16)
)和第三个参数中的Personne
(但我不知道它是如何从&Vendeur::getNom
到Qstring Personne::function()
的,除非涉及到一些继承或其他东西)。您可能需要发布比这更多的代码(尤其是类定义)。
【讨论】:
以上是关于函数指针和继承的主要内容,如果未能解决你的问题,请参考以下文章