函数指针和继承

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】:

&amp;Vendeur::getNom,尽管是可通过Vendeur 访问的成员,但似乎具有QString (Personne::*)() 类型。这使得T2 在模板参数推导过程中变得模棱两可:是Vendeur 还是Personne

创可贴的解决方法是让trie 的调用者承担显式转换为QString (Vendeur::*)() 的负担,从而导致以下调用:

trie(vend, &Vendeurs::getVend, static_cast<QString (Vendeur::*)()>(&Vendeur::getNom));

考虑到每次我们希望传递的criterion 来自基类时,我们都可能发现相同的错误,这非常冗长且不方便。

更好的解决方案是在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,而&amp;Vendeur::getNom会隐式转换为QString (Vendeur::*)()

【讨论】:

【参考方案2】:

您似乎同时试图将T2 的第二个参数中的Vendeur 约束为trie(因为Vendeur Vendeurs::getVend(quint16))和第三个参数中的Personne(但我不知道它是如何从&amp;Vendeur::getNomQstring Personne::function() 的,除非涉及到一些继承或其他东西)。您可能需要发布比这更多的代码(尤其是类定义)。

【讨论】:

以上是关于函数指针和继承的主要内容,如果未能解决你的问题,请参考以下文章

通过继承和函数指针绕过保护

成员函数指针和继承

具有类私有成员和函数指针的继承结构

C++ 函数指针参数和类继承自动转换

可与仅派生方法一起使用的 C++ 继承函数指针

指向继承类实例的指针作为函数参数