我正在创建一个链表类,它使用内部Link
类和模板类来定义可以存储在链表中的类型。
但是,在我的方法popValue
应该返回模板类型T
,我无法初始化默认类型(在本例中,称为Point
),尽管存储的类型在每个链接中都有一个默认构造函数 - 根据these questions,表示T retval = T() / T{}
应该有效。
此外,鉴于T retval
不是引用类型,我不明白错误消息是如何对应的?
因此,问题的方法:
template<typename T>
T LinkedList<T>::popValue() {
T retval = T(); //This doesnt work
Point test = Point(); //But this is allowed?
if (head != 0) {
Link *n = head;
retval = head->value;
head = head->next;
delete n;
}
return retval;
}
出现以下错误value-initialization of reference type 'Point&'
:
如何将此模板变量初始化为默认值,以便如果LinkedList中没有元素,则可以返回此默认值,前提是其他问题中概述的方法似乎不起作用?
非常感谢,
大卫
修改
通过评论,我查看了LinkedList.h
的专业化,发现我将其用作LinkedList<Point&> list;
时出现了重大错误。
在模板表单中使用时,这意味着T
正在尝试实例化引用类型 - 这是不允许的。
作为参考,我已经包含了一个简洁的代码清单,列出了我认为相关的代码(但为了简洁起见已删除了非重要的包含,保护和名称空间)......:
LinkedList.h
template<typename T>
class LinkedList {
public:
struct Link { ///< Struct inside the class LinkedList
Link(T val): value(val), next(0){};
T value;
Link *next;
~Link() {
delete next;
} //Iteratively delete
};
T popValue(); ///< returns first element and deletes Link.
private:
Link *head; // this is the private member variable. It is just a pointer to the first Node
};
#include "LinkedList.cpp" //Allows definition of template methods in .cpp file
LinkedList.cpp(仅限错误方法)
template<typename T>
T LinkedList<T>::popValue() {
T retval = T(); //This doesnt work
Point test = Point(); // But this does
if (head != 0) {
Link *n = head;
retval = head->value;
head = head->next;
delete n;
}
return retval;
}
答案 0 :(得分:1)
根据错误消息
引用类型“Point&amp;”的
T很可能是参考类型。
您可以通过以下方式查看:
static_assert(std::is_reference<T>::value == false, "");
通过使用std::remove_reference
(std::decay
在这种情况下也很有用),您可以获得T引用的类型,这将使您能够定义非引用变量。
#include <type_traits>
int main() {
using T = int &;
std::remove_reference_t<T> b = std::remove_reference_t<T>();
return 0;
}
如果未声明“x_t”:
#include <type_traits>
int main() {
using T = int &;
typename std::remove_reference<T>::type b =
typename std::remove_reference<T>::type();
return 0;
}
不太相关:
“存储”引用会给您带来很多麻烦,因为通常我们不会检查引用是否引用任何内容,&ref != nullptr
。可能,您不希望以这种方式实现popValue:
template<typename T>
T LinkedList<T>::popValue() {
if (head != 0) {
Link *n = head;
T retval = head->value;
head = head->next;
delete n;
return retval;
} else {
std::remove_reference_t<T> x = std::remove_reference_t<T>();
return x; // very bad when T is reference
}
}
返回由output参数弹出的元素仍然是一个选项(只要在列表为空时保持输出参数不变),但也许你只想存储没有引用。