Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与指向继承方法的模板化函数指针一起使用的模板化方法存在问题_C++_Templates_Inheritance_C++98 - Fatal编程技术网

C++ 与指向继承方法的模板化函数指针一起使用的模板化方法存在问题

C++ 与指向继承方法的模板化函数指针一起使用的模板化方法存在问题,c++,templates,inheritance,c++98,C++,Templates,Inheritance,C++98,我似乎无法理解特定模板化方法的情况 类似的模板化方法已经在我的代码库中出现了一段时间,并且以与Bar::Bar(IFoo&)相同的方式使用,唯一的区别是传入的函数是继承的 我有一个接口IFoo,它定义了有问题的模板函数 struct IFoo { template<class T> void doSomething(bool (T::*method)(int), T *instance) { std::cout << (instance-&

我似乎无法理解特定模板化方法的情况

类似的模板化方法已经在我的代码库中出现了一段时间,并且以与
Bar::Bar(IFoo&)
相同的方式使用,唯一的区别是传入的函数是继承的

我有一个接口
IFoo
,它定义了有问题的模板函数

struct IFoo {
    template<class T>
    void doSomething(bool (T::*method)(int), T *instance) {
        std::cout << (instance->*method)(5) << "\n";
    }
};
当我尝试使用
IFoo::doSomething
时,编译器就是看不到匹配的函数

int main() {
    Bar b;
    IFoo foo;
    foo.doSomething(&Bar::setValue, &b);
}
我收到以下编译器消息
错误:调用'
IFoo::doSomething(bool(父项::*)(int),Bar*)
'时没有匹配的函数

我真正感到惊讶的是,对于模板化的
IFoo::doSomething
函数,我没有得到一个候选建议


请仅使用C++98解决方案。

正如错误所述,
Bar::setValue
的类型实际上是
bool(父项::*)(int)
。这会干扰
doSomething
的模板参数推导,因为它有两个
T
s需要相同。您可以通过强制转换
this
来帮助编译器进行推断:

int main() {
    Bar b;
    IFoo foo;
    foo.doSomething(&Bar::setValue, static_cast<Parent*>(&b));
}

不调用自己而不是虚拟方法?很抱歉,你仍然被迫使用C++ 98代码> DO /Cuff>是C++中的关键字。你不能像这样命名一个方法一个do方法是私有的,并且与我尝试使用的公共版本有不同的参数。我将在我的示例中编辑并重命名该方法,它在我的Codebase中没有调用,你可以使用2个模板参数,让Callback隐式地将条向上投射到父指针:@JVApen谢谢你的链接。我也这么认为,但无可否认,我太懒了,无法验证它是否有效;)我本来打算添加
静态断言(std::is_base_of_v)
,但是,这已经不存在22年了ago@lancegerday“静态_cast在计算上很昂贵”这肯定是一个误解。你为什么这么认为?还有一个模版黑魔法“演绎拦截器”:
template struct type_identity{/*从C++20*/typedef T type;};模板void doSomething(bool(T:::*方法)(int),typename type_identity::type*实例)
,其中
doSomething(&Bar::setValue,&b)
起作用,因为只有
&Bar::setValue
有助于选择
T=Parent
。然后,向上投射变成隐式的。
int main() {
    Bar b;
    IFoo foo;
    foo.doSomething(&Bar::setValue, static_cast<Parent*>(&b));
}
template<class T, class U>
void doSomething(bool (T::*method)(int), U *instance);