【问题标题】:C++: Function pointer as Template argument instead of functorC++:函数指针作为模板参数而不是仿函数
【发布时间】:2014-08-03 14:42:54
【问题描述】:

我一直在尝试创建这个类,它可以使用默认函子作为参数,或者用户可以根据需要提供一个。但我无法将函数指针作为模板参数传递。你能帮我理解我错过了什么吗?

template <typename T>
struct CheckFunctor
{
    bool operator()(T obj)
    {
        return true;
    }
};



template <typename _Ty,
class _Pr = CheckFunctor<_Ty>
>
class MyClass
{
    typedef _Ty                     mapped_type;
    typedef _Pr                     CanBeCleaned_type;

    _Ty data;
    CanBeCleaned_type predicate;

public:  

    void SomeMethod()
    {
            if( predicate(data))
            {
              std::cout << "Do something";
            }
    }
       MyClass(_Ty timeOutDuration, _Pr pred = _Pr())
        : data( timeOutDuration), predicate( pred)
    {}   
};

template< typename T>
struct CheckEvenFunctor
{
   bool operator()(T val)
    {
       return (val%2 == 0);
    }
};


bool CheckEven( int val)
{
    return (val%2 == 0);
}

int main()
{
//Usage -1
    MyClass<int> obj1( 5);

//Usage- 2
 MyClass< int, CheckEven> obj2(6, CheckEven);  //Error: 'CheckEven' is not a valid template type argument for parameter '_Pr'

 //Usage -3 
 MyClass<int, CheckEvenFunctor<int>>( 7);
}

【问题讨论】:

  • 问题是你试图使用一个对象(CheckEven)作为一个类型(class _Pr
  • 我可以用我的 MyCLass 做点什么,让它同时接受 functionPtr 和 Functors。我想保持 MyClass 的简单使用。

标签: c++ templates function-pointers functor


【解决方案1】:

您尝试将CheckEven 作为类型参数传递,即使CheckEven 不是类型而是函数(bool(int) 类型)。您应该将类​​型定义为指向您要传递的函数类型的指针。 decltype 在这里很方便:

MyClass< int, decltype(&CheckEven)> obj2(6, CheckEven);

也可以创建工厂函数,让编译器推导出模板参数:

template<class T, class F>
MyClass<T, F> makeClass(T timeOutDuration, F pred) {
    return {timeOutDuration, pred};
}

auto obj2 = makeClass(6, CheckEven);

【讨论】:

    【解决方案2】:

    可以允许模板参数是函数,但您的MyClass 期望第二个参数是类型,而不是函数。您可能认为模板特化可用于允许您定义 MyClass 以在第二个模板参数中也采用一个函数,但它不起作用。模板特化允许您针对作为模板参数传递的特定类型修改 MyClass 的行为,但这些类型仍必须与 MyClass 的模板定义匹配,即两个参数都是类型。

    您可以修改您正在实例化的MyClass 的类型,方法是将第二个参数设置为函数指针类型,如另一个答案中所建议的那样,但是您将失去模板扩展使您对函数的调用内联的优势。另一种解决方案是创建一个帮助类,它将您的函数转换为仿函数,并使用它来创建您的 MyClass 实例。

    template <bool P (int)>
    struct F {
        bool operator()(int obj) { return P(obj); }
    };
    
    //...
    MyClass<int, F<CheckEven> > obj2(6);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多