首页 > 解决方案 > 重载函数的地址与所需类型不匹配

问题描述

所以我使用了一个看起来像这样的构造函数:

deduplicator(std::function<void(const std::vector<uint8_t>&, std::vector<uint8_t>&)> chunk_fingerprinter);

我使用这个函数作为块指纹:

void sha1_hash(const std::vector<uint8_t>& data, std::vector<uint8_t>& hash);

我像这样初始化对象:

deduplication::deduplicator dedup = deduplication::deduplicator(harpocrates::hashing::sha1_hash);

导致此错误:

../src/split-deduplication/split-deduplication.cpp:35:32: error: address of overloaded function 'sha1_hash' does not match required type 'void'
    void* hash_func = (void*) &harpocrates::hashing::sha1_hash;
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../resolve_symlinks/harpocrates/src/harpocrates/hashing.hpp:34:10: note: candidate function
    void sha1_hash(const std::vector<uint8_t>& data, std::vector<uint8_t>& hash);
         ^
../resolve_symlinks/harpocrates/src/harpocrates/hashing.hpp:40:10: note: candidate function
    void sha1_hash(const uint8_t* data, const size_t size, uint8_t* hash);

但如果我涉足黑暗艺术并这样做:

    void (*sha1_hash)(const std::vector<uint8_t>&, std::vector<uint8_t>&) = harpocrates::hashing::sha1_hash;
    deduplication::deduplicator dedup = deduplication::deduplicator(sha1_hash);

然后它起作用了,有人可以向我解释为什么会这样吗?如果这有所作为,我正在使用 C++17

编辑:犯了一个错误,我已将sha1_hash函数更新为我调用的正确函数

解决方案:

我在同一个名称空间中有两个具有相同名称的函数,如下所述,在这种情况下,干净的解决方案是拆分为两个名称空间。正如人们所提到的,这是因为编译器无法选择使用哪一个。

标签: c++overloadingoverload-resolution

解决方案


从错误消息中我想那sha1_hash是超载的。


void (*sha1_hash)(const std::vector<uint8_t>&, std::vector<uint8_t>&) = harpocrates::hashing::sha1_hash;之所以起作用,是因为在执行重载函数重载决议的地址时,sha1_hash会选择签名与类型匹配的重载,即void (*)(const std::vector<uint8_t>&, std::vector<uint8_t>&).

在所有这些上下文中,从重载集中选择的函数是其类型与目标期望的函数指针、函数引用或成员函数类型的指针匹配的函数:被初始化的对象或引用,左侧赋值、函数或运算符参数、函数的返回类型、强制转换的目标类型或模板参数的类型。

您也可以使用static_cast明确指定。

auto sha1_hash = static_cast<void (*)(const std::vector<uint8_t>&, std::vector<uint8_t>&)>(harpocrates::hashing::sha1_hash);

正如错误消息所说,void* hash_func = (void*) &harpocrates::hashing::sha1_hash;不起作用,因为void*与重载的任何签名都不匹配sha1_hash,然后重载解析失败。

顺便说一句:尝试将函数指针转换为void*似乎是个坏主意,尤其是在这种情况下您根本不需要它。


推荐阅读