简体   繁体   English

将成员 function 作为模板参数传递

[英]Passing a member function as template argument

I have a hash table class.我有一个 hash 表 class。 It has a template parameter hashFunction :它有一个模板参数hashFunction

#include <string>

template<class KeyType> using hashFunction_t = size_t(size_t, const KeyType&);

template< class KeyType, class ValueType, int nHashGroups,
    hashFunction_t<KeyType> hashFunction >
class HashTable
{

};

class Entity
{
    //djb2
    size_t stringHash(size_t nGroups, const std::string& key)
    {
        unsigned long hash = 5381;
        const char* str = key.c_str();

        int c = 0;
        while (c = *str++)
            hash = ((hash << 5) + hash) + c;

        return hash % nGroups;
    }

    HashTable <std::string, int, 10, stringHash> ht; 
};

int main()
{
    Entity{};
}

I would prefer to hide stringHash function inside the Entity class as a private function but doing that gives me an error:我宁愿将stringHash function 隐藏在Entity class 中作为私有 function 但这样做会给我一个错误:

Error (active)  E0458   argument of type 
"size_t (Entity::*)(size_t nGroups, const std::string &key)" 
is incompatible with template parameter of type 
"hashFunction_t<std::string> *"

How can I do this?我怎样才能做到这一点?

The problem is that you are trying to use a pointer-to-member as a type template parameter, and this is not supported, basically because when you define a type you don't bind that type to any specific object.问题是您试图使用指向成员的指针作为类型模板参数,这不受支持,主要是因为当您定义一个类型时,您没有将该类型绑定到任何特定的 object。

When (as suggested in a comment) you make stringHash static, then you no longer need the object, so it can be used to define the type.当(如评论中所建议的)您制作stringHash static 时,您不再需要 object,因此可以使用它来定义类型。

If you still need to have stringHash from a non-static member, then you can change the template to something like the below.如果您仍然需要来自非静态成员的stringHash ,那么您可以将模板更改为如下所示。 Be aware that you have to pass the object to the HashTable in order to call the hashFunction .请注意,您必须将 object 传递给HashTable才能调用hashFunction Also, keep an eye on the syntax to call it.另外,请注意调用它的语法。

template<class KeyType, class Obj> using hashFunction_t =
    size_t(Obj::*)(size_t, const KeyType&);

template< class KeyType, class ValueType, int nHashGroups,
    class Obj, hashFunction_t<KeyType, Obj> hashFunction>
class HashTable
{
public:
    explicit HashTable(Obj& obj) : m_obj{obj} {
        (m_obj.*hashFunction)(10, ""); // arguments just for illustrative purposes
    }

private:
    Obj& m_obj; // keep a reference to the object to call the method
                // be careful with dangling references
};

class Entity
{
    size_t stringHash(size_t nGroups, const std::string& key)
    /* ... */

    // Pass a reference to the object
    HashTable <std::string, int, 10, Entity, &Entity::stringHash> ht{*this};
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM