使用指向函数的指针作为模板参数

Rom*_*098 0 c++ templates function-pointers

(C++)我有很多Entry类,并且得到了BaseProcessor接口,它包含了Entry处理逻辑.(见下面的代码)

Entry不提供运算符<().BaseProcessor提供指向较少(Entry,Entry)函数的指针,该函数特定于特定的BaseProcessor实现.

我可以使用函数指针来比较程序中的Entry实例.但是我需要为Entry类创建std :: set(或std :: map,或其他使用less()的东西).我试图使用std :: binary_function派生类将它传递给std :: set,但看起来我无法将函数指针值传递给模板.

我怎样才能做到这一点?用C++ 03可以吗?

谢谢.

struct Entry
{
  // ...
private: 
  bool operator< (const Entry &) const; // Should be defined by BaseProcessor.
};

typedef bool (*LessFunc)(const Entry &, const Entry &);

class BaseProcessor
{
public:
  // ...
  virtual LessFunc getLessFunc () const = 0;
};

// ...

BaseProcessor *processor = getProcessor();
LessFunc lessfunc = processor->getLessFunc();

Entry e1;
Entry e2;
bool isLess = lessfunc(e1, e2);  // OK

typedef std::set<Entry, ???> EntrySetImpl; // how to use lessfunc here?
EntrySetImpl entries;   
Run Code Online (Sandbox Code Playgroud)

Dou*_*oug 5

你试过这个吗?

typedef std::set<Entry, LessFunc> EntrySetImpl;
EntrySetImpl entries(lessfunc);
Run Code Online (Sandbox Code Playgroud)

请注意,您需要将比较函数或对象的类型指定为模板参数set,然后在实际创建集合时为其提供比较函数或对象的实例.


我会编辑我的答案以解决您的后续问题,因为它更容易一些.

您可以像这样定义模板:

template <LessFunc func> class MyContainer { /*code*/ };
Run Code Online (Sandbox Code Playgroud)

但是,问题是,您必须指定一个特定的函数,而不是函数指针变量,作为模板参数.所以,例如,这没关系:

bool CompareEntries1(const Entry &, const Entry &);
MyContainer<CompareEntries1> container;
Run Code Online (Sandbox Code Playgroud)

......但这不行

bool CompareEntries1(const Entry &, const Entry &);
LessFunc lessfunc = &CompareEntries1; //or any other way of getting a LessFunc
MyContainer<lessfunc> container;
Run Code Online (Sandbox Code Playgroud)

如果您已经使用过数组模板类,boost::array那么之前您可能已经看过类似的东西了.例如,您可以编写array<int, 10>声明一个10元素的数组,但不能编写array<int, abs(x)>.数组的大小必须是编译器在编译程序时可以被告知的内容,但在运行之前.(关于允许的内容有一套非常具体的规则 - 即使看起来编译器应该能够计算出模板参数是什么,LessFunc如上例所示,它仍然必须遵循特定的规则.在这种情况下函数指针模板参数,参数必须是函数的名称,或者&后跟函数的名称.)