在之前的項目中,我遇到過類似的錯誤,所以我決定從新方法開始,並且仍然遇到同樣的問題。我有一個鍵值對模板類,除了流操作符之外,一切都正常。我有<<
接受kvp_node<key, elem> &kvp
或kvp_node<key, elem> *kvp
的模板。我能夠創建kvp_node
對象並使用它們的成員函數,而不存在任何問題。但是,如果我嘗試做一些事情,如:模板化的流操作員,未解決的外部問題
kvp_node<char, int> test('A', 10);
std::cout << test;
它給我的無法解析的外部操作錯誤。 我覺得我已經正確定義了我的流操作符。如果我嘗試只是做:
kvp_node<char, int> name('J', 12);
std::cout << name.elm_();
它的工作原理沒有錯誤,這就是爲什麼這是混亂的,因爲所有的ostream操作確實是
os << (kvp_node<key, elem> test(key, elem)).elm_()
這是我的頭文件:
#ifndef DICT_H_
#define DICT_H_
#include<iostream>
#include<fstream>
//Stores Key Value pairs in a linked node can be used
//to implement various KV based ADTs
//kvp_nodes can be compared using normal comparator
//operations. These operations will use the comparators
//for the key class type, so if the key class is a user
//defined type, they must define the comparators for the
//class
template<typename key, typename elem>
class kvp_node {
bool setinel;
key k_val;
elem e_val;
kvp_node<key, elem> *next;
kvp_node<key, elem> *prev;
public:
//default constructor
kvp_node();
//use this constructor
kvp_node(key k, elem e, bool set = false);
//destructor
~kvp_node();
//copy constructor
kvp_node(const kvp_node<key, elem> &kvp);
//assignment constructor
void operator=(const kvp_node<key, elem> &kvp_);
//returns keyvalue
key key_();
//returns element
elem elm_();
//sets key value
void set_key(key k);
//sets element value
void set_elm(elem e);
//comparators, all will use the default comparators for the key type
bool operator==(kvp_node<key, elem> &kvp);
bool operator>=(kvp_node<key, elem> &kvp);
bool operator<=(kvp_node<key, elem> &kvp);
bool operator>(kvp_node<key, elem> &kvp);
bool operator<(kvp_node<key, elem> &kvp);
//returns next node
kvp_node<key, elem> *gnext();
//returns previous node
kvp_node<key, elem> *gprev();
//node linking functions
//sets the next node
void set_next(kvp_node<key, elem> *kvp);
//sets the previous node
void set_prev(kvp_node<key, elem> *kvp);
//links node a forward to b and b backward to a
void link_nodes(kvp_node<key, elem> *A, kvp_node<key, elem> *B);
//setinel functions
//makes setinel
void set_set();
//returns setinel value
bool set();
//standard io stream operators
//ostream <<
friend std::ostream& operator<<(std::ostream &os, kvp_node<key, elem> &kvp);
friend std::ostream& operator<<(std::ostream &os, kvp_node<key, elem> *kvp);
//istream
//add later
//standard file stream operators
//ofstream <<
friend std::ofstream& operator<<(std::ofstream &fo, kvp_node<key, elem> &kvp);
friend std::ofstream& operator<<(std::ofstream &fo, kvp_node<key, elem> *kvp);
//ifstream
//add later
};
//constructors, destructors, assignment
template<typename key, typename elem>
kvp_node<key, elem>::kvp_node() {
}
template<typename key, typename elem>
kvp_node<key, elem>::kvp_node(key k, elem e, bool set) {
k_val = k;
e_val = e;
setinel = set;
}
template<typename key, typename elem>
kvp_node<key, elem>::~kvp_node(){
}
template<typename key, typename elem>
kvp_node<key, elem>::kvp_node(const kvp_node<key, elem> &kvp) {
k_val = kvp.key_();
e_val = kvp.elm_();
setinel = kvp.set();
}
template<typename key, typename elem>
void kvp_node<key, elem>::operator=(const kvp_node<key, elem> &kvp) {
k_val = kvp.key_();
e_val = kvp.elm_();
setinel = kvp.set();
}
// ==================================
//get object values
template<typename key, typename elem>
key kvp_node<key, elem>::key_() {
return k_val;
}
template<typename key, typename elem>
elem kvp_node<key, elem>::elm_() {
return e_val;
}
template<typename key, typename elem>
bool kvp_node<key, elem>::set() {
return setinel;
}
// ==================================
//set object values
template<typename key, typename elem>
void kvp_node<key, elem>::set_key(key k) {
k_val = k;
}
template<typename key, typename elem>
void kvp_node<key, elem>::set_elm(elem e) {
e_val = e;
}
template<typename key, typename elem>
void kvp_node<key, elem>::set_set() {
setinel = true;
}
// =================================
//get neighbor kv pair nodes
template<typename key, typename elem>
kvp_node<key, elem> *kvp_node<key, elem>::gnext() {
return next;
}
template<typename key, typename elem>
kvp_node<key, elem> *kvp_node<key, elem>::gprev() {
return prev;
}
// =================================
//set neighbor kv pair nodes
template<typename key, typename elem>
void kvp_node<key, elem>::set_next(kvp_node<key, elem> *kvp) {
next = kvp;
}
template<typename key, typename elem>
void kvp_node<key, elem>::set_prev(kvp_node<key, elem> *kvp) {
prev = kvp;
}
template<typename key, typename elem>
void kvp_node<key, elem>::link_nodes(kvp_node<key, elem> *A, kvp_node<key, elem> *B) {
A->set_next(B);
B->set_prev(A);
}
// ==================================
//comparison operators
template<typename key, typename elem>
bool kvp_node<key, elem>::operator<(kvp_node<key, elem> &kvp) {
return (k_val < kvp.key_()) ? (true) : (false);
}
template<typename key, typename elem>
bool kvp_node<key, elem>::operator>(kvp_node<key, elem> &kvp) {
return (k_val > kvp.key_()) ? (true) : (false);
}
template<typename key, typename elem>
bool kvp_node<key, elem>::operator<=(kvp_node<key, elem> &kvp) {
return (k_val <= kvp.key_()) ? (true) : (false);
}
template<typename key, typename elem>
bool kvp_node<key, elem>::operator>=(kvp_node<key, elem> &kvp) {
return (k_val >= kvp.key_()) ? (true) : (false);
}
template<typename key, typename elem>
bool kvp_node<key, elem>::operator==(kvp_node<key, elem> &kvp) {
return (k_val == kvp.key_()) ? (true) : (false);
}
// ==================================
//stream operators
template<typename key, typename elem>
std::ostream &operator<<(std::ostream &os, kvp_node<key, elem> &kvp) {
os << kvp.elm_();
return os;
}
template<typename key,typename elem>
std::ostream &operator<<(std::ostream &os, kvp_node<key, elem> *kvp) {
os << kvp->elm_();
return os;
}
#endif
它是如何使用所有其他類成員,但流操作符不工作?
非常好,爲什麼從類中刪除流運算符聲明修復了這個問題? 'const const kvp_node&kvp'和'kvp_node const&kvp' –
Anandamide
之間的區別是什麼?從類中刪除好友功能不能解決問題。我只是刪除他們,因爲他們沒有必要,因爲你有所有私人成員的獲得者。修正它在'operator <<'定義中使用const kvp_node實例的東西。 – msmith81886
啊有道理。我可以繼續我的項目感謝你:) – Anandamide