如果泛型类型 T 有合适的构造函数可供使用,如何知道它?
How to know a generic type T if it has an appropriate constructor for use?
我正在实现一个双向链表,它的头部和尾部都有哨兵节点,假设这个 class 名为 List
。 Node
是 List
中的私有结构。这个class有一个私有方法Init
用于初始化头节点和尾节点,在List
的构造函数中调用。
template<typename T>
class List {
public:
List() {
Init();
}
...
private:
struct Node {
T data;
Node* prev;
Node* next;
// Constructors
};
size_t size;
Node* head;
Node* tail;
void Init() {
// Codes arise some problem if instances of T have no default constructor.
head = new Node;
tail = new Node;
head->prev = nullptr;
head->next = tail;
tail->prev = head;
tail->next = nullptr;
size = 0;
}
};
现在的问题是,如果 T
的实例没有默认构造函数,我无法使用 head = new Node;
和 tail = new Node;
创建哨兵节点。 new
运算符总是分配一块内存并构造它。在构造Node
对象时,必须使用T
的一些构造函数来初始化Node
中的data
字段。
有没有办法检查 T
的哪些构造函数(复制和移动构造函数除外)我可以用来构造 T
类型的变量 data
?或者我可以只初始化 Node
中的 prev
和 next
字段,而不初始化 data
字段吗?
你的代码有一个类型 T,它应该遵循你需要的概念。
在你的情况下,你希望它是默认可构造的。如果模板的实例化器不提供符合的 T,它会得到一个大的模板错误。
您可以在您的代码中添加一个 static_assert,以提供更好的消息(如果您的方法未被直接使用,则可以更早地提供)
您可以使用:static_assert(is_default_constructible_v)
。
存在更多变体,如果它不应该抛出...,请参阅 documentation
在 C++20 中,您也可以使用概念来限制 T。我对它们不甚了解,所以我会留给您寻找正确的语法。
还有其他解决方案,例如存储 std::optional,或在 init 函数上使用可变参数来构造 T。
在这种情况下,如果您不介意放置新闻,您可能希望使用 std::is_constructible. std::aligned_storage 限制代码也可以。一切都取决于你想用这个实现什么。
我正在实现一个双向链表,它的头部和尾部都有哨兵节点,假设这个 class 名为 List
。 Node
是 List
中的私有结构。这个class有一个私有方法Init
用于初始化头节点和尾节点,在List
的构造函数中调用。
template<typename T>
class List {
public:
List() {
Init();
}
...
private:
struct Node {
T data;
Node* prev;
Node* next;
// Constructors
};
size_t size;
Node* head;
Node* tail;
void Init() {
// Codes arise some problem if instances of T have no default constructor.
head = new Node;
tail = new Node;
head->prev = nullptr;
head->next = tail;
tail->prev = head;
tail->next = nullptr;
size = 0;
}
};
现在的问题是,如果 T
的实例没有默认构造函数,我无法使用 head = new Node;
和 tail = new Node;
创建哨兵节点。 new
运算符总是分配一块内存并构造它。在构造Node
对象时,必须使用T
的一些构造函数来初始化Node
中的data
字段。
有没有办法检查 T
的哪些构造函数(复制和移动构造函数除外)我可以用来构造 T
类型的变量 data
?或者我可以只初始化 Node
中的 prev
和 next
字段,而不初始化 data
字段吗?
你的代码有一个类型 T,它应该遵循你需要的概念。
在你的情况下,你希望它是默认可构造的。如果模板的实例化器不提供符合的 T,它会得到一个大的模板错误。
您可以在您的代码中添加一个 static_assert,以提供更好的消息(如果您的方法未被直接使用,则可以更早地提供)
您可以使用:static_assert(is_default_constructible_v)
。
存在更多变体,如果它不应该抛出...,请参阅 documentation
在 C++20 中,您也可以使用概念来限制 T。我对它们不甚了解,所以我会留给您寻找正确的语法。
还有其他解决方案,例如存储 std::optional,或在 init 函数上使用可变参数来构造 T。 在这种情况下,如果您不介意放置新闻,您可能希望使用 std::is_constructible. std::aligned_storage 限制代码也可以。一切都取决于你想用这个实现什么。