讓我一步一步來。問題是我無法實體化模板類。請幫助我在哪里做錯了。
我有一個模板類,如下所示:
template <typename K, typename V>
class HashNodeDefaultPrint {
public:
void operator()(K key, V value) {}
};
然后我有一個屬于上述模板的特定類,即 K = int, V = int
class HashNodePrintIntInt {
public:
void operator()(int key, int value) {
printf ("k = %d, v = %d", key, value);
}
};
同樣,我還有另一個模板類,如下所示:
template <typename K>
class defaultHashFunction {
public:
int operator()(K key) {
return 0;
}
};
同樣,我有一個特定的類,它與 K = int 的上述模板相匹配
class HashFunctionInteger {
public:
int operator()(int key) {
return key % TABLE_SIZE;
}
};
現在我創建一個 HashNode 模板化類,如下所示:
template <typename K, typename V, typename F = HashNodeDefaultPrint<K, V>>
class HashNode {
public:
K key;
V value;
F printFunc;
HashNode *next;
HashNode(K key, V value, F func) {
this->key = key;
this->value = value;
next = NULL;
}
};
最后是一個 HashMap 模板類,如下所示:
template <typename K, typename V, typename F = defaultHashFunction<K>, typename F2 = HashNodeDefaultPrint<K,V>>
class HashMap {
private:
HashNode<K, V, F2> *table_ptr;
F hashfunc;
public:
HashMap() {
table_ptr = new HashNode<K,V, F2> [TABLE_SIZE]();
}
};
現在在 main() 中,我正在實體化 HashMap 類,如下所示:
int
main(int argc, char **argv) {
HashMap<int, int, HashFunctionInteger, HashNodePrintIntInt> hmap;
return 0;
}
但我看到編譯錯誤:
vm@ubuntu:~/src/Cplusplus/HashMap$ g -g -c hashmap.cpp -o hashmap.o
hashmap.cpp: In instantiation of ‘HashMap<K, V, F, F2>::HashMap() [with K = int; V = int; F = HashFunctionInteger; F2 = HashNodePrintIntInt]’:
hashmap.cpp:157:65: required from here
hashmap.cpp:107:21: error: no matching function for call to ‘HashNode<int, int, HashNodePrintIntInt>::HashNode()’
107 | table_ptr = new HashNode<K,V, F2> [TABLE_SIZE]();
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hashmap.cpp:30:9: note: candidate: ‘HashNode<K, V, F>::HashNode(K, V, F) [with K = int; V = int; F = HashNodePrintIntInt]’
30 | HashNode(K key, V value, F func) {
| ^~~~~~~~
hashmap.cpp:30:9: note: candidate expects 3 arguments, 0 provided
hashmap.cpp:27:7: note: candidate: ‘constexpr HashNode<int, int, HashNodePrintIntInt>::HashNode(const HashNode<int, int, HashNodePrintIntInt>&)’
27 | class HashNode {
| ^~~~~~~~
hashmap.cpp:27:7: note: candidate expects 1 argument, 0 provided
hashmap.cpp:27:7: note: candidate: ‘constexpr HashNode<int, int, HashNodePrintIntInt>::HashNode(HashNode<int, int, HashNodePrintIntInt>&&)’
hashmap.cpp:27:7: note: candidate expects 1 argument, 0 provided
vm@ubuntu:~/src/Cplusplus/HashMap$
當我正確指定特定的類名來定義模板變數時,這個實體化有什么問題?
uj5u.com熱心網友回復:
你想得太復雜了:-)
如果您已經使用模板,您可以根據需要專門化它們。那不需要新的類名!
從...開始:
template <typename K, typename V>
struct HashNodePrint {
void operator()(K key, V value) {}
};
// and specialize for int,int:
template<>
struct HashNodePrint<int,int> {
void operator()(int key, int value) {
printf ("k = %d, v = %d", key, value);
}
};
同樣對于
template <typename K>
struct HashFunction {
int operator()(K key) {
return 0;
}
};
template <>
struct HashFunction<int> {
int operator()(int ) {
return 0;
}
};
我希望您不再需要模板默認函式,因為您不再需要手動指定專用函式。它們現在會自動映射到專用版本。
這將在這里結束:
template <typename K, typename V>
class HashNode {
public:
K key;
V value;
HashFunction<K> printFunc;
HashNode *next;
HashNode(K key, V value) {
this->key = key;
this->value = value;
next = NULL;
}
HashNode(){}
};
但是您的HashNode. 也許您生成了一個默認值,或者您在呼叫中放置了一些默認值,或者根本不從構造傳遞這些值。我不知道您想通過以默認方式生成它來實作什么。
template <typename K, typename V >
class HashMap {
private:
HashNode<K, V> *table_ptr;
HashFunction<K> hashfunc;
public:
HashMap(/* put maybe a container type here */) {
// no idea how big your TABLE_SIZE will be.
//
table_ptr = new HashNode<K,V> [TABLE_SIZE]{ /* and forward as needed */};
}
};
int main() {
HashMap<int, int> hmap{ /* pass args maybe in container or std::initializer_list */;
return 0;
}
uj5u.com熱心網友回復:
template <typename K, typename V, typename F = defaultHashFunction<K>, typename
F2 = HashNodeDefaultPrint<K,V>>
class HashMap {
private:
HashNode<K, V, F2> *table_ptr;
F hashfunc;
public:
HashMap() {
table_ptr = new HashNode<K,V, F2> [TABLE_SIZE](); <----
}
};
您正在嘗試新建一個沒有默認建構式的 HashNode<K, V, F2> 陣列。默認建構式被洗掉,因為定義了以下建構式:
HashNode(K key, V value, F func) {
this->key = key;
this->value = value;
next = NULL;
}
uj5u.com熱心網友回復:
您可以通過在類模板中提供默認建構式來解決此錯誤, HashNode如下所示:
template <typename K, typename V, typename F = HashNodeDefaultPrint<K, V>>
class HashNode {
public:
HashNode(K key, V value, F func) {
this->key = key;
this->value = value;
next = NULL;
}
HashNode() = default; //DEFAULT CONSTRUCTOR ADDED
};
這是因為您在撰寫時需要默認建構式:
table_ptr = new HashNode<K,V, F2> [TABLE_SIZE](); //<--- default constructor needed here
在上面的陳述句中new HashNode<K,V, F2> [TABLE_SIZE]()使用了默認建構式。
需要默認建構式
如下面給出的例子所示,當我們撰寫new Name[10](). 出于同樣的原因,您需要類模板的默認建構式HashNode。
struct Name
{
Name()
{
std::cout<<"default constructor called"<<std::endl;
}
~Name()
{
std::cout<<"destructor called"<<std::endl;
}
};
int main() {
Name *ptr = new Name[10](); //this will use the default constructor
delete []ptr;
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/402507.html
標籤:
上一篇:如何迭代可變引數模板型別的數量
下一篇:訪問記憶體中的位
