首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何声明模板化函数,以便在类构造函数/函数中传递

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

Stack Overflow用户
提问于 2018-04-04 09:46:55
回答 3查看 70关注 0票数 3

我希望将用户定义的函数传递给需要用户定义的匹配函数的类。在过去的C时代,我会使用一个函数指针,其中包含了void*参数。但一定有更好的方法..。

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

我需要做的是:

代码语言:javascript
复制
#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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-04-04 09:51:57

代码语言:javascript
复制
#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;
}
票数 6
EN

Stack Overflow用户

发布于 2018-04-04 09:55:22

如果Tmatch_key应该与hashmap的K相同,则可以将签名作为hashmap的一部分。

代码语言:javascript
复制
template <typename T>
struct hashmap {
    typedef bool (*match_key)(const T& key1, const T& key2);
    ....
}

...otherwise i将使比较器的类型成为第二个模板参数:

代码语言:javascript
复制
template <typename K, typename C>
struct hashmap {
     C cmp;
     hashmap(const K& key, C matchfunc) : key_(key), cmp(matchfunc) { }
     ...
}

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

票数 4
EN

Stack Overflow用户

发布于 2018-04-06 10:02:19

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

此处函子,指满足下列条件的任何类型的T:

  1. 其中有过载呼叫运营商;

  1. 具有用户定义的转换函数,使其能够静态地传递到函数指针。

无论在哪种情况下,任何这类类型的对象都是可调用的,并且可以将其用作函数的名称。

这方面的一个例子是性病:较少,它在使用需要比较两个对象的算法时经常使用。

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

代码语言:javascript
复制
template <class K, class Cmp = std::less<>>
class hashmap {
public:
    hashmap<K>(const K& key, Cmp _cmp = {}): key_(key), cmp(_cmp) { }

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

private:
    const K key_;
    Cmp cmp;
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49647846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档