C++ 模板如何重载运算符和访问私有 属性
C++ template how to overloading operator and accessing private property
我目前正在尝试实现一个简单的基于模板的链表,该链表采用 C++11 中的通用 key/value-pair。应通过 += 运算符将元素添加到列表中。代码如下所示:
列表
// Forward declarations
template<typename K, typename V>
class list;
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &list, const std::tuple<K, V> ele) {
if (!list.head) {
// list is empty
list.head = new element(ele, nullptr);
}
return list;
};
// Class definition
template<typename K, typename V>
class list {
private:
struct element {
const K key;
const V value;
element *next;
element(const std::tuple<K, V> tuple, element *ele) :
key(std::get<0>(tuple)),
value(std::get<1>(tuple)),
next(ele) { }
};
element *head = nullptr;
public:
friend list<K, V> &operator+=<>(list<K, V> &list, const std::tuple<K, V> ele);
};
我无法编译它。我是否必须将运算符的实现放入前向声明或 class 本身?如果我把它放在前向声明中,就像在代码片段中一样,我似乎无法使用 "list.head = new element(ele, nullptr);"。错误:“元素”
之前需要类型说明符
如果我将其放入 class 本身,即使它是朋友,我也无法访问 list.head。
你应该只在class模板定义之前(前向声明之后)留下函数模板的声明,告诉编译器友元声明中指定的operator+=
是一个模板。然后再定义它。例如
// Forward declarations
template<typename K, typename V>
class list;
// declaration of function template
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &l, const std::tuple<K, V> ele);
// Class definition
template<typename K, typename V>
class list {
...
friend list<K, V> &operator+=<>(list<K, V> &l, const std::tuple<K, V> ele);
};
// definition of function template
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &l, const std::tuple<K, V> ele) {
if (!l.head) {
// list is empty
l.head = new typename list<K, V>::element(ele, nullptr);
}
return l;
}
PS:
不要将参数命名为list
,这与class模板list
的名称冲突。
element
是一个嵌套结构,在 operator+=
中你应该像 typename list<K, V>::element
.
那样指定它
使用名称 list
(与 std::list
相同)不是一个好主意。
我目前正在尝试实现一个简单的基于模板的链表,该链表采用 C++11 中的通用 key/value-pair。应通过 += 运算符将元素添加到列表中。代码如下所示:
列表
// Forward declarations
template<typename K, typename V>
class list;
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &list, const std::tuple<K, V> ele) {
if (!list.head) {
// list is empty
list.head = new element(ele, nullptr);
}
return list;
};
// Class definition
template<typename K, typename V>
class list {
private:
struct element {
const K key;
const V value;
element *next;
element(const std::tuple<K, V> tuple, element *ele) :
key(std::get<0>(tuple)),
value(std::get<1>(tuple)),
next(ele) { }
};
element *head = nullptr;
public:
friend list<K, V> &operator+=<>(list<K, V> &list, const std::tuple<K, V> ele);
};
我无法编译它。我是否必须将运算符的实现放入前向声明或 class 本身?如果我把它放在前向声明中,就像在代码片段中一样,我似乎无法使用 "list.head = new element(ele, nullptr);"。错误:“元素”
之前需要类型说明符如果我将其放入 class 本身,即使它是朋友,我也无法访问 list.head。
你应该只在class模板定义之前(前向声明之后)留下函数模板的声明,告诉编译器友元声明中指定的operator+=
是一个模板。然后再定义它。例如
// Forward declarations
template<typename K, typename V>
class list;
// declaration of function template
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &l, const std::tuple<K, V> ele);
// Class definition
template<typename K, typename V>
class list {
...
friend list<K, V> &operator+=<>(list<K, V> &l, const std::tuple<K, V> ele);
};
// definition of function template
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &l, const std::tuple<K, V> ele) {
if (!l.head) {
// list is empty
l.head = new typename list<K, V>::element(ele, nullptr);
}
return l;
}
PS:
不要将参数命名为
list
,这与class模板list
的名称冲突。element
是一个嵌套结构,在operator+=
中你应该像typename list<K, V>::element
. 那样指定它
使用名称
list
(与std::list
相同)不是一个好主意。