Я занимаюсь рефакторингом API, который я сделал пару лет назад, и привел полиморфную реализацию общих структур данных (списки, карты, наборы, деревья, графики), доступных по адресу http://www.data -types.com.Для структур, требующих сравнения значений (например, хеш-таблица), я заставил их использовать компараторы C, и все идет хорошо.
В следующей версии, однако, я пытаюсь выровнять поведение компараторов так, чтобы пользователи выигралине требуется создавать его, когда он уже может быть выведен.Все идет хорошо, пока я не попытаюсь преобразовать аргумент метода в аргумент шаблона.Пример кода уменьшен до голой кости:
#include <iostream>
#include <cstddef>
#include <stdexcept>
template<typename VALUE>
class HashTable {
public:
HashTable(int (*comparator)(const VALUE&,const VALUE&), std::size_t (*hasher)(const VALUE&)){
std::cout << "HashTable constructor called" << std::endl;
}
bool contains(const VALUE& value, int (*customCompare)(const VALUE&,const VALUE&)) const{
return false;
}
~HashTable(){
std::cout << "HashTable destructor called" << std::endl;
}
};
template<typename _KEY, typename _VALUE>
struct MapEntry {
_KEY key;
_VALUE value;
};
template<typename KEY, typename VALUE, int (*comparator)(const KEY&, const KEY&)>
static inline int compareMapKey(const MapEntry<KEY,VALUE>& left, const MapEntry<KEY,VALUE>& right) {
return comparator(left.key, right.key);
}
template<typename KEY, typename VALUE, int (*comparator)(const VALUE&, const VALUE&)>
static inline int compareMapValue(const MapEntry<KEY,VALUE>& left, const MapEntry<KEY,VALUE>& right) {
return comparator(left.value, right.value);
}
template<typename KEY, typename VALUE, std::size_t (*hash)(const KEY&)>
static inline std::size_t hashMapKey(const MapEntry<KEY, VALUE>& element) {
return hash(element.key);
}
template<typename KEY, typename VALUE, int (*compareByKey)(const KEY&, const KEY&), std::size_t (*hashByKey)(const KEY&)>
class HashMap {
public:
HashMap(){
hashTable = new HashTable<MapEntry<KEY,VALUE>>(compareMapKey<KEY, VALUE, compareByKey>, hashMapKey<KEY, VALUE, hashByKey>);
std::cout << "HashMap constructor called" << std::endl;
}
bool containsValue(const VALUE& value, int (*comparator)(const VALUE&, const VALUE&)) const{
MapEntry<KEY,VALUE> mapEntry;
mapEntry.value = value;
return hashTable->contains(mapEntry, compareMapValue<KEY, VALUE, comparator>);
}
~HashMap(){
delete hashTable;
std::cout << "HashMap destructor called" << std::endl;
}
private:
HashTable<MapEntry<KEY,VALUE>>* hashTable;
};
static inline int comparator(const long& left, const long& right) {
if(left<right) return -1;
else if (left>right) return 1;
else return 0;
}
static inline std::size_t hash(const long& item) {
return item;
}
int main() {
long val = 1;
HashMap<long, long, comparator, hash> map;
map.containsValue(val, comparator);
std::cout << "!!!Hello World!!!" << std::endl;
return 0;
}
Это отказывается компилировать, выдавая мне эту ошибку:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Test.d" -MT"src/Test.o" -o "src/Test.o" "../src/Test.cpp"
../src/Test.cpp: In instantiation of ‘bool HashMap<KEY, VALUE, compareByKey, hashByKey>::containsValue(const VALUE&, int (*)(const VALUE&, const VALUE&)) const [with KEY = long int; VALUE = long int; int (* compareByKey)(const KEY&, const KEY&) = comparator; std::size_t (* hashByKey)(const KEY&) = hash]’:
../src/Test.cpp:78:35: required from here
../src/Test.cpp:53:79: error: no matching function for call to ‘HashTable<MapEntry<long int, long int> >::contains(MapEntry<long int, long int>&, <unresolved overloaded function type>)’ return hashTable->contains(mapEntry, compareMapValue<KEY, VALUE, comparator>);
../src/Test.cpp:12:7: note: candidate: bool HashTable<VALUE>::contains(const VALUE&, int (*)(const VALUE&, const VALUE&)) const [with VALUE = MapEntry<long int, long int>] bool contains(const VALUE& value, int (*customCompare)(const VALUE&,const VALUE&)) const{
../src/Test.cpp:12:7: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘int (*)(const MapEntry<long int, long int>&, const MapEntry<long int, long int>&)’
Кто-нибудь знает решение выше?Мои навыки C ++ стали более грубыми, так как я больше не работаю на этом языке ...