C++ 在C++;
我想要一个基于给定回调函数检查特定条件的函数 考虑到这一准则:C++ 在C++;,c++,templates,callback,c2664,C++,Templates,Callback,C2664,我想要一个基于给定回调函数检查特定条件的函数 考虑到这一准则: class Foo{ template <class ParamType> struct IsGood { typedef bool (*Check)(typename const ParamType*, int other); }; template< typename ParamType > void DoSmth(IsGood<ParamType>::Check isGood, co
class Foo{
template <class ParamType>
struct IsGood
{
typedef bool (*Check)(typename const ParamType*, int other);
};
template< typename ParamType >
void DoSmth(IsGood<ParamType>::Check isGood, const ParamType* param){
//...
if(isGood(param, some_int_calculated_here)) doSmthElse();
}
(显示问题的所有构造示例)
编译器将无法获得该值,并抛出错误C2664“无法在bool(ParamType,int)中从bool(int*,int)转换参数1”
我有一个不使用的解决方案
template< typename ParamType, Check >
void DoSmth(Check isGood, const ParamType param)
模板
无效DoSmth(检查是否良好,常数参数类型参数)
检查功能的必要声明是什么
最好的解决方案是在函数本身中获取IsGood()头。使用functor模板可以解决您的问题:
template< typename Functor, typename ParamType >
void DoSmth(Functor isGood, const ParamType param){
//...
if(isGood(param, some_int_calculated_here)) doSmthElse();
}
template
void DoSmth(函子isGood,常量ParamType param){
//...
如果(isGood(参数,此处计算的部分))doSmthElse();
}
现在,您可以使用任何具有兼容签名的函数或函子对象(不一定是将
ParamType
和int
作为参数的函数或函子对象)。否则,您将需要使用具有该确切签名的函数 问题在于模板函数的第一个参数是不可推断的:
template< typename ParamType >
void DoSmth(typename IsGood<ParamType>::Check isGood, const ParamType param)
// ^ ^^^^^^^^^^^^^^^^^^^^^^^^
// missing nested type! not deducible!
模板
void DoSmth(typename IsGood::Check IsGood,const ParamType param)
// ^ ^^^^^^^^^^^^^^^^^^^^^^^^
//缺少嵌套类型!不可推断!
简单的选项是就地展开签名(C++03,C++11):
模板
void DoSmth(void(*isGood)(ParamType,int),const ParamType param)
//注意:删除的“const”无论如何都会被编译器删除
或者,如果您有C++11,您可以用模板别名替换IsGood::Check
:
template <typename T>
using IsGood = void (*)(T,int);
template< typename ParamType >
void DoSmth(IsGood<ParamType> isGood, const ParamType param)
模板
使用IsGood=void(*)(T,int);
模板
void DoSmth(IsGood IsGood,const ParamType param)
或者重构代码,采用一个函子,使其更灵活、更简单、更高效,因为编译器更容易内联调用:
template <typename P, typename T>
void DoSmth(P predicate, T param) {
if (predicate(param,somethingelse)) { ...
}
模板
void DoSmth(P谓词,T参数){
如果(谓词(param,somethingelse)){。。。
}
我在回答之前没有看到最后一行。为什么使用表示函子的模板参数不是一个选项?对我来说很有效:(在添加/删除typename后,如果需要)@user2093113checkEqualFloat
不起作用。@mfontani确实起作用,但这是因为问题中指定的checkEqualFloat
与IsGood::Check
函数签名不匹配。更正签名以int
作为第二个参数起作用:。@user2093113:您的代码正在工作。I just忘记了一件事:ParamTypes是作为指针提供的。我更新了这个问题。很抱歉。我认为它应该是一样的。但是它可以在IsGood中匹配指针并使用“DoSmth(IsGood::Check)”,但是它看起来很奇怪,正如前面提到的,我想避免函子在函数头本身中指定函数签名
template <typename T>
using IsGood = void (*)(T,int);
template< typename ParamType >
void DoSmth(IsGood<ParamType> isGood, const ParamType param)
template <typename P, typename T>
void DoSmth(P predicate, T param) {
if (predicate(param,somethingelse)) { ...
}