1

基本上,我有一个运行某种算法的模板类,并且该算法需要一个similarity(T t1, T t2)函数,该函数返回一个定义两个 T 类型对象的相似程度的双精度数。这个相似度函数根据T的定义有很大的不同,所以这个类的调用者需要定义相似度函数。我假设函数指针是有序的,但是如何将函数指针中的函数保存为成员函数以在算法中使用?

也就是说,我想传入similarity(T t1, T t2)类的构造函数,并能够在整个类中将其作为成员函数调用。我怎么做?谢谢

4

4 回答 4

2

您不能在运行时将成员函数添加到类中。

您可以编写一个成员函数,通过函数指针调用提供的函数:

class MyClass {
    typedef double (*similarity_fn_type)(T t1, T t2);
    similarity_fn_type similarity_fn;
  public:
    MyClass(similarity_fn_type ptr) : similarity_fn(ptr) {}
    double similarity(T t1, T t2) {
        return similarity_fn(t1, t2);
    }
};

或者,您可以similarity_fn成员设为公开。调用它的语法使它看起来像一个成员函数,但你可能认为它不是很好的封装。

于 2012-07-24T15:27:07.583 回答
1

有更简洁、面向对象的方法可以做到这一点。其中之一是使用该函数传递一个对象,类似于 Java 如何允许重新实现与 Comparator 类的比较。这意味着为每个similarity().

在您的情况下,您可能会发现 C++11 用于实现比较和散列函数的解决方案更有用。它涉及创建特殊的功能对象。有关示例,请参见std::lessstd::hash

于 2012-07-24T15:35:06.973 回答
0

定义const适当类型的函数指针成员:

typedef double(*Similarity)(T, T);
const Similarity similarity;

让构造函数接受该类型的函数:

Class(Similarity f) : similarity(f) {}

然后调用该函数与调用普通成员函数的语法相同:

frobnicate(similarity(foo, bar));

如果该成员是public,则无法从您下方更改,因为它是const

于 2012-07-24T15:34:30.067 回答
0

我做了一些类似于抽象出遍历集合的过程的事情。我使用谓词来指定实际的搜索条件:

void MyClass::Copy(Class &destination, const Class &source, const std::function<bool (const Effect&)> &predicate)
{
    for (size_t i = 0; i < Effect::Max; ++i)
    {
        const Effect *const pEffect = source.GetEffect(i);
        if (predicate(*pEffect))
        {
            // Do something
        }
    }
}

void MyClass::CopyInner(Class &destination, const Class &source)
{
    this->Copy(destination, source, [](const Effect &effect)
    {
        return effect.IsInner();
    });
}

注意:这使用了一些 C++11 特性。

于 2012-07-24T15:30:35.837 回答