2010-10-22 130 views
0

(C++)我有很多Entry类,并且获得了包含Entry处理逻辑的BaseProcessor接口。 (见下面的代码)使用函数指针作为模板参数

该条目不提供运营商<()。 BaseProcessor提供了一个指向特定BaseProcessor实现的less(Entry,Entry)函数的指针。

我可以使用函数指针来比较我的程序中的Entry实例。然而,我需要创建std :: set(或std :: map或其他使用less())的Entry类。我试图使用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; 

回答

5

你试过吗?

typedef std::set<Entry, LessFunc> EntrySetImpl; 
EntrySetImpl entries(lessfunc); 

请注意,您需要指定的比较函数或对象作为模板参数set类型,然后给它一个比较函数的实例或对象时,实际上创建了一组。


我将修改我的回答对您解决后续问题,因为它是一个更容易一些。

您可以定义模板是这样的:

template <LessFunc func> class MyContainer { /*code*/ }; 

然而,美中不足的是,你必须指定一个特定功能,不是一个函数指针变量,作为模板参数。因此,举例来说,这是确定:

bool CompareEntries1(const Entry &, const Entry &); 
MyContainer<CompareEntries1> container; 

...但是这是不正常:

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

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

+0

是的,它的工作原理。万分感谢。 – Rom098 2010-10-22 11:50:15

+0

但是...它看起来像没有办法使用函数指针值作为非类型模板参数。对?像“template class Comparator {...}” – Rom098 2010-10-22 11:54:34

+0

@Roman - 你也可以这样做,对于你写的类,但是'set'不能像那样工作。但是,您指定为模板参数的'LessFunc'必须是编译时常量(例如,它不能是调用函数的结果)。 – Doug 2010-10-22 11:59:39