адрес перегруженной функции не соответствует требуемому типу - PullRequest
1 голос
/ 08 ноября 2019

Итак, я использую конструктор, который выглядит следующим образом:

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 на ту, которую я называю

Решение:

У меня было две функции в одном и том же пространстве имен с одним и тем же именем, как показано ниже, чистое решение в этом случае было разделить на два пространства имен. И как уже упоминали люди, это было потому, что компилятор не мог выбрать, какой из них использовать.

1 Ответ

4 голосов
/ 08 ноября 2019

Из сообщения об ошибке я предполагаю, что 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* кажется плохой идеей, особенно в этом случае она вам вообще не нужна.

...