【问题标题】:How to define a template function with two relative parameters如何定义具有两个相对参数的模板函数
【发布时间】:2021-03-29 08:46:56
【问题描述】:

我正在尝试定义一个函数,它允许我们调用标准哈希函数或一些自定义函数,并返回哈希值。

这是一个关于如何使用我的函数的示例:

auto res = myfunc<std::hash>(2);    //hash the integer 2 with the function std::hash
auto res2 = myfunc<std::hash>("abc");    // hash the string "abc" with the function std::hash
auto res3 = myfunc<customHasher>(2);    // hash the integer 2 with some custom hash function

我尝试编写如下代码:

template<void (*T)(U)>
size_t myfunc(const U &u)
{
    return T<U>(u);
}

T应该是函数指针,std::function或者lambda,UT的参数类型。

但是无法编译。

main.cpp:14:23: error: expected ‘>’ before ‘(’ token
     template<void (*T)(U)>
                       ^
main.cpp:15:25: error: ‘U’ does not name a type
     size_t myfunc(const U &u)
                         ^
main.cpp: In function ‘size_t myfunc(const int&)’:
main.cpp:17:18: error: ‘U’ was not declared in this scope
         return T<U>(u);

好吧,我知道template&lt;void (*T)(U)&gt; 一定是错误的,因为U 没有定义。但我不知道如何解决它。

【问题讨论】:

  • std::hash 不是函数。修复你对函数指针的尝试(假设它是可能的)仍然不会让你走得更远。
  • @StoryTeller-UnslanderMonica 好的,我在帖子中添加了一行:“T 应该是函数指针、std::function 或 lambda,U 是 T 的参数类型。” .
  • customhasher 是模板吗? return T&lt;U&gt;(u); 建议 T 是一个模板,这是否需要或者你可以通过例如 std::hash&lt;int&gt; 吗?
  • @largest_prime_is_463035818 是的,customhasher 就像std::hash 一样,是一个参数的模板。
  • @largest_prime_is_463035818 这就是重点。你看,我不想传递std::hash&lt;int&gt;,我只想简单传递一个std::hash

标签: c++ templates functor


【解决方案1】:

您需要声明这两个参数。而且,std::hash 是一个类模板,而不是一个函数。您可以使用模板模板参数:

#include <cstdint>
#include <functional>
#include <iostream>
#include <string>

template<typename T, template<typename> typename H = std::hash>
std::size_t myfunc(const T &t)
{
    return H<T>{}(t);
}

int main() {
    std::cout << myfunc(std::string{"123"});
}

不过,要将其用于您的 customHasher,它也需要是一个类模板(带有 operator())。

注意需要在main中显式构造一个字符串,否则T不能推导出为std::string

【讨论】:

  • 酷,不知道这个。 C++17 有这个吗?
  • @kabaus c++98 有这个 ;)
  • @Yves 否,因为“abc”是一个 c 字符串文字,没有 std::hash 专门化。 you will need to specify a string
  • @Yves 我不是模板向导,但您可以使用重载或专业化,例如link。编辑:忘记了功能模板不允许部分模板专业化。重载似乎有效。
  • @Yves 请注意,从 c-string 到 std::string 的转换不是免费的。您可以考虑使用支持多种字符串格式的std::hash&lt;std::string_view&gt;(但不属于自己)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多