实施 emplace_back() 二进制“=”时出错:未找到接受 'T *' 类型右手操作数的运算符
Error in implementing emplace_back() binary '=': no operator found which takes a right-hand operand of type 'T *'
下面的代码,用于我的链表实现,特别是下面的 emplace_back。我做错了什么以及如何解决?
我得到的错误是:
Build started...
1>------ Build started: Project: so_list_emplace, Configuration: Debug Win32 ------
1>main.cpp
1list.hpp(191,19): error C2280: 'list<President>::node::node(void)': attempting to reference a deleted function
1>list.hpp(15): message : compiler has generated 'list<President>::node::node' here
1>list.hpp(15,1): message : 'list<President>::node::node(void)': function was implicitly deleted because a data member 'list<President>::node::value' has either no appropriate default constructor or overload resolution was ambiguous
1>list.hpp(12): message : see declaration of 'list<President>::node::value'
1>main.cpp(29): message : see reference to function template instantiation 'void list<President>::emplace_back<const char(&)[15],const char(&)[13],int>(const char (&)[15],const char (&)[13],int &&)' being compiled
1>main.cpp(29): message : see reference to function template instantiation 'void list<President>::emplace_back<const char(&)[15],const char(&)[13],int>(const char (&)[15],const char (&)[13],int &&)' being compiled
1>list.hpp(192,10): error C2679: binary '=': no operator found which takes a right-hand operand of type 'T *' (or there is no acceptable conversion)
1> with
1> [
1> T=President
1> ]
1>main.cpp(22,13): message : could be 'President &President::operator =(const President &)'
1>list.hpp(190,1): message : while trying to match the argument list '(T, T *)'
1> with
1> [
1> T=President
1> ]
1>Done building project "so_list_emplace.vcxproj" -- FAILED.
list.hpp 实施:
#ifndef LIST_HPP_
#define LIST_HPP_
#include <cstddef>
#include <initializer_list>
#include <utility>
template< typename T >
class list {
public:
struct node {
T value;
node* next;
node* prior;
};
struct iterator {
iterator(node* nod) : ptr_(nod) {}
iterator& operator++() {
if (ptr_) {
ptr_ = ptr_->next;
}
return *this;
}
iterator operator++(T) {
auto old = *this;
if (ptr_) {
ptr_ = ptr_->next;
}
return old;
}
T& operator*() const { return ptr_->value; }
T* operator->() { return &ptr_->value; }
bool operator==(const iterator& other) { return ptr_ == other.ptr_; }
bool operator!=(const iterator& other) { return ptr_ != other.ptr_; }
node* ptr_;
};
list() : head_(nullptr), tail_(nullptr), size_(0) {}
// O(n)
template< typename input_iterator >
list(input_iterator first, input_iterator last) : head_(nullptr), tail_(nullptr), size_(0) {
for (auto it = first; it != last; ++it) {
push_back(*it);
}
}
// O(n)
list(std::initializer_list<T> init) : list<T>(init.begin(), init.end()) {}
// O(n)
list(const list& other) : head_(nullptr), tail_(nullptr), size_(0) {
auto it = other.begin();
while (it != nullptr) {
push_back(*it);
++it;
}
size_ = other.size();
}
// O(n)
list& operator=(const list& other) {
if (this != &other) {
clear();
auto it = other.begin();
while (it != nullptr) {
push_back(*it);
++it;
}
size_ = other.size();
}
return *this;
}
list(list&& other) : head_(other.head_), tail_(other.tail_), size_(other.size()) {
other.size_ = 0;
other.head_ = nullptr;
other.tail_ = nullptr;
}
list& operator=(list&& other) {
head_ = other.head_;
tail_ = other.tail_;
size_ = other.size();
other.clear();
other.head_ = nullptr;
other.tail_ = nullptr;
other.size_ = 0;
}
// O(n)
~list() {
clear();
}
// O(n)
void clear() {
if (head_) {
node* current = head_;
while (current) {
node* next = current->next;
delete current;
current = next;
}
}
head_ = nullptr;
tail_ = nullptr;
size_ = 0;
}
// O(1)
bool empty() const {
return head_ == nullptr;
}
// O(1)
void push_back(const T& value) {
node* newnode = make_node(value);
if (tail_) {
node* oldtail = tail_;
oldtail->next = newnode;
newnode->prior = oldtail;
tail_ = newnode;
}
else {
head_ = tail_ = newnode;
}
++size_;
}
// O(1)
size_t size() const {
return size_;
}
iterator begin() {
return iterator(head_);
}
const iterator begin() const {
return iterator(head_);
}
iterator end() {
return nullptr;
}
const iterator end() const {
return nullptr;
}
// O(1)
T& front() { return *iterator(head_); }
const T& front() const { return *iterator(head_); }
// O(1)
T& back() { return *iterator(tail_); }
const T& back() const { return *iterator(tail_); }
// O(1)
void pop_back() {
if (tail_) {
node* newtail = tail_->prior;
if (newtail) {
newtail->next = nullptr;
}
else {
// means that head_ has also been erased
head_ = nullptr;
}
delete tail_;
tail_ = newtail;
--size_;
}
}
template<typename... P>
void emplace_back(P&&... v)
{
node* newnode = new node;
newnode->value = new T(std::forward<P>(v)...);
newnode->next = nullptr;
newnode->prior = nullptr;
if (tail_) {
node* oldtail = tail_;
oldtail->next = newnode;
newnode->prior = oldtail;
tail_ = newnode;
}
else {
head_ = tail_ = newnode;
}
++size_;
}
private:
node* make_node(const T& value) {
node* newnode = new node;
newnode->value = value;
newnode->next = nullptr;
newnode->prior = nullptr;
return newnode;
}
node* head_;
node* tail_;
size_t size_;
};
#endif // LIST_HPP_
main.cpp 锻炼:
#include "list.hpp"
#include <iostream>
#include <string>
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
President(President&& other)
: name(std::move(other.name)), country(std::move(other.country)), year(other.year)
{
std::cout << "I am being moved.\n";
}
President& operator=(const President& other) = default;
};
int main() {
list<President> elections;
elections.emplace_back("Nelson Mandela", "South Africa", 1994);
}
您的问题是 node
正在尝试构建 President
,但 President
没有默认构造函数。你需要构造一个 node
和一个 President
,就像在这个构造函数中一样:
node(T const &v) : value(v) { }
因为 emplace_back
尝试就地构造一个对象,您还需要添加一个构造函数来使用传入的参数构造 value
。
template <typename ...Args>
node(Args &&...v) : value(std::forward<Args>(v)...) { }
最后,更新您的 emplace_back
函数以在构建时转发参数。
node* newnode = new node(std::forward<P>(v)...);
这是用 gcc 和 clang 为我编译的。
问题(反映在错误中)是:
list::node::node()
没有默认构造函数,因为它是implicitly deleted.
President
没有默认构造函数,因为您有 用户定义的构造函数 用于 President
,因此编译器将 不合成你的默认构造函数。
President
没有operator=
。
要解决这些问题你需要添加以下内容:
node
的默认构造函数,例如 node
中的 node() = default();
。
President
的默认构造函数,例如 President
中的 President() = default;
。
- 定义(重载)
President
的赋值运算符。
下面的代码,用于我的链表实现,特别是下面的 emplace_back。我做错了什么以及如何解决?
我得到的错误是:
Build started...
1>------ Build started: Project: so_list_emplace, Configuration: Debug Win32 ------
1>main.cpp
1list.hpp(191,19): error C2280: 'list<President>::node::node(void)': attempting to reference a deleted function
1>list.hpp(15): message : compiler has generated 'list<President>::node::node' here
1>list.hpp(15,1): message : 'list<President>::node::node(void)': function was implicitly deleted because a data member 'list<President>::node::value' has either no appropriate default constructor or overload resolution was ambiguous
1>list.hpp(12): message : see declaration of 'list<President>::node::value'
1>main.cpp(29): message : see reference to function template instantiation 'void list<President>::emplace_back<const char(&)[15],const char(&)[13],int>(const char (&)[15],const char (&)[13],int &&)' being compiled
1>main.cpp(29): message : see reference to function template instantiation 'void list<President>::emplace_back<const char(&)[15],const char(&)[13],int>(const char (&)[15],const char (&)[13],int &&)' being compiled
1>list.hpp(192,10): error C2679: binary '=': no operator found which takes a right-hand operand of type 'T *' (or there is no acceptable conversion)
1> with
1> [
1> T=President
1> ]
1>main.cpp(22,13): message : could be 'President &President::operator =(const President &)'
1>list.hpp(190,1): message : while trying to match the argument list '(T, T *)'
1> with
1> [
1> T=President
1> ]
1>Done building project "so_list_emplace.vcxproj" -- FAILED.
list.hpp 实施:
#ifndef LIST_HPP_
#define LIST_HPP_
#include <cstddef>
#include <initializer_list>
#include <utility>
template< typename T >
class list {
public:
struct node {
T value;
node* next;
node* prior;
};
struct iterator {
iterator(node* nod) : ptr_(nod) {}
iterator& operator++() {
if (ptr_) {
ptr_ = ptr_->next;
}
return *this;
}
iterator operator++(T) {
auto old = *this;
if (ptr_) {
ptr_ = ptr_->next;
}
return old;
}
T& operator*() const { return ptr_->value; }
T* operator->() { return &ptr_->value; }
bool operator==(const iterator& other) { return ptr_ == other.ptr_; }
bool operator!=(const iterator& other) { return ptr_ != other.ptr_; }
node* ptr_;
};
list() : head_(nullptr), tail_(nullptr), size_(0) {}
// O(n)
template< typename input_iterator >
list(input_iterator first, input_iterator last) : head_(nullptr), tail_(nullptr), size_(0) {
for (auto it = first; it != last; ++it) {
push_back(*it);
}
}
// O(n)
list(std::initializer_list<T> init) : list<T>(init.begin(), init.end()) {}
// O(n)
list(const list& other) : head_(nullptr), tail_(nullptr), size_(0) {
auto it = other.begin();
while (it != nullptr) {
push_back(*it);
++it;
}
size_ = other.size();
}
// O(n)
list& operator=(const list& other) {
if (this != &other) {
clear();
auto it = other.begin();
while (it != nullptr) {
push_back(*it);
++it;
}
size_ = other.size();
}
return *this;
}
list(list&& other) : head_(other.head_), tail_(other.tail_), size_(other.size()) {
other.size_ = 0;
other.head_ = nullptr;
other.tail_ = nullptr;
}
list& operator=(list&& other) {
head_ = other.head_;
tail_ = other.tail_;
size_ = other.size();
other.clear();
other.head_ = nullptr;
other.tail_ = nullptr;
other.size_ = 0;
}
// O(n)
~list() {
clear();
}
// O(n)
void clear() {
if (head_) {
node* current = head_;
while (current) {
node* next = current->next;
delete current;
current = next;
}
}
head_ = nullptr;
tail_ = nullptr;
size_ = 0;
}
// O(1)
bool empty() const {
return head_ == nullptr;
}
// O(1)
void push_back(const T& value) {
node* newnode = make_node(value);
if (tail_) {
node* oldtail = tail_;
oldtail->next = newnode;
newnode->prior = oldtail;
tail_ = newnode;
}
else {
head_ = tail_ = newnode;
}
++size_;
}
// O(1)
size_t size() const {
return size_;
}
iterator begin() {
return iterator(head_);
}
const iterator begin() const {
return iterator(head_);
}
iterator end() {
return nullptr;
}
const iterator end() const {
return nullptr;
}
// O(1)
T& front() { return *iterator(head_); }
const T& front() const { return *iterator(head_); }
// O(1)
T& back() { return *iterator(tail_); }
const T& back() const { return *iterator(tail_); }
// O(1)
void pop_back() {
if (tail_) {
node* newtail = tail_->prior;
if (newtail) {
newtail->next = nullptr;
}
else {
// means that head_ has also been erased
head_ = nullptr;
}
delete tail_;
tail_ = newtail;
--size_;
}
}
template<typename... P>
void emplace_back(P&&... v)
{
node* newnode = new node;
newnode->value = new T(std::forward<P>(v)...);
newnode->next = nullptr;
newnode->prior = nullptr;
if (tail_) {
node* oldtail = tail_;
oldtail->next = newnode;
newnode->prior = oldtail;
tail_ = newnode;
}
else {
head_ = tail_ = newnode;
}
++size_;
}
private:
node* make_node(const T& value) {
node* newnode = new node;
newnode->value = value;
newnode->next = nullptr;
newnode->prior = nullptr;
return newnode;
}
node* head_;
node* tail_;
size_t size_;
};
#endif // LIST_HPP_
main.cpp 锻炼:
#include "list.hpp"
#include <iostream>
#include <string>
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
President(President&& other)
: name(std::move(other.name)), country(std::move(other.country)), year(other.year)
{
std::cout << "I am being moved.\n";
}
President& operator=(const President& other) = default;
};
int main() {
list<President> elections;
elections.emplace_back("Nelson Mandela", "South Africa", 1994);
}
您的问题是 node
正在尝试构建 President
,但 President
没有默认构造函数。你需要构造一个 node
和一个 President
,就像在这个构造函数中一样:
node(T const &v) : value(v) { }
因为 emplace_back
尝试就地构造一个对象,您还需要添加一个构造函数来使用传入的参数构造 value
。
template <typename ...Args>
node(Args &&...v) : value(std::forward<Args>(v)...) { }
最后,更新您的 emplace_back
函数以在构建时转发参数。
node* newnode = new node(std::forward<P>(v)...);
这是用 gcc 和 clang 为我编译的。
问题(反映在错误中)是:
list::node::node()
没有默认构造函数,因为它是implicitly deleted.President
没有默认构造函数,因为您有 用户定义的构造函数 用于President
,因此编译器将 不合成你的默认构造函数。President
没有operator=
。
要解决这些问题你需要添加以下内容:
node
的默认构造函数,例如node
中的node() = default();
。President
的默认构造函数,例如President
中的President() = default;
。- 定义(重载)
President
的赋值运算符。