如何声明模板化函数,以便可以在类构造函数/函数中传递

时间:2018-04-04 09:46:56

标签: c++ function-pointers function-prototypes

我想将用户定义的函数传递给需要用户定义的匹配函数的类。在C的旧时代,我会使用带有void *参数的函数指针。但必须有更好的方法......

这大致是我想要做的事情。我的一个限制是我所在的平台没有标准库。但是可以使用基本的核心语言C ++ 11。

我需要做什么:

#include <iostream>

using namespace std;

// TODO - replace this C construct with C++ equivalent
//typedef bool(*match_key)(const void* key1, const void* key2);

// somehow declare this as a typedef?  need a way to declare a signature in C++
typedef template<class T>
bool (*match_key)(const T& key1, const T& key2);


// *** User defined matching function
bool mymatcher(const int i, const int j) {
    return i == j;
}

template<class K>
class hashmap {
public:
    hashmap<K>(const K& key, match_key matchfunc) : key_(key), cmp(matchfunc) { }

    bool matched(const K& key) {
        return cmp(key_, key);
    }

private:
    const K key_;
    match_key cmp;
};


int main()
{
    int i = 3;
    int j = 4;

    hashmap<int> hm(i, mymatcher);
    cout << "i matches j? " << (hm.matched(j) ? "yes" : "no") << endl;

    return 0;
}

3 个答案:

答案 0 :(得分:6)

#include <iostream>

using namespace std;

// TODO - replace this C construct with C++ equivalent
//typedef bool(*match_key)(const void* key1, const void* key2);

// somehow declare this as a typedef?  need a way to declare a signature in C++
typedef template<class T>
using match_key = bool (*)(const T& key1, const T& key2);


// *** User defined matching function
bool mymatcher(const int i, const int j) {
    return i == j;
}

template<class K>
class hashmap{
public:
    hashmap(const K& key, match_key<K> matchfunc) : key_(key), cmp(matchfunc) { }

    bool matched(const K& key) {
        return cmp(key_, key);
    }

private:
    const K key_;
    match_key<K> cmp;
};


int main()
{
    int i = 3;
    int j = 4;

    hashmap<int> hm(i, mymatcher);
    cout << "i matches j? " << (hm.matched(j) ? "yes" : "no") << endl;

    return 0;
}

答案 1 :(得分:4)

如果T的{​​{1}}应该与hashmap的match_key相同,则可以将签名作为K的一部分:

hashmap

...否则我会将比较器的类型作为第二个模板参数:

template <typename T>
struct hashmap {
    typedef bool (*match_key)(const T& key1, const T& key2);
    ....
}

这将为用户提供更大的灵活性,同时也为长编译错误打开了大门。

答案 2 :(得分:0)

将函数作为指针传递的方式在C ++中非常有限。它无法在C ++中容纳任何可调用对象。具体来说,它将阻止在C ++中使用仿函数。

这里的仿函数,指任何满足的类型T:

  1. 已经重载了调用操作符;
  2. 或者

    1. 具有用户定义的转换函数,可以将其静态转换为函数指针。
    2. 无论是哪种情况,这种类型的任何对象都是可调用的,并且可以像它们是函数名一样使用。

      这方面的一个例子是std::less,它在使用需要比较2个对象的算法时经常使用。

      为了能够传递任何可调用对象,你必须对函数的类型进行模板化:

      constructor(props){
          super(props);
      
          this.state = {
              price:false
          };
      }