如何知道泛型类型T是否有合适的构造函数可供使用



我正在实现一个双链表,它的头和尾都有sentinel节点,比如这个名为List的类。CCD_ 2是CCD_ 3中的私有结构。这个类有一个用于初始化head和tail节点的私有方法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;创建sentinel节点。new操作符总是分配一块内存并构造它。在构造Node对象时,它必须使用T的一些构造函数来初始化Node中的data字段。

有没有办法检查T的哪些构造函数(复制和移动构造函数除外(可以用来构造T类型的变量data?或者我只能初始化Node中的prevnext字段,而不初始化Node0字段?

您的代码有一个类型T,它应该遵循您所需要的概念。

在您的情况下,您希望它是默认可构造的。如果模板的实例化器没有提供符合的t,它将得到一个很大的模板错误。

您可以在代码中添加static_assert,以提供更好的消息(如果您的方法没有直接使用,则可以更早地提供(

您可以使用:static_assert(is_default_constructible_v)。存在更多的变体,如果它不应该抛出。。。,参见文件

在C++20中,你也可以使用概念来限制T。我对它们不熟悉,所以我将让你来找到正确的语法。

还有其他解决方案,比如存储std::optional,或者在init函数上使用可变参数来构造T。在这种情况下,您可能希望使用std::is_constructible来限制代码。std::aligned_storage也可以工作,如果你不介意安置新闻。这一切都取决于你想用它实现什么。

相关内容

  • 没有找到相关文章

最新更新