实现emplace_back()二进制' =':没有发现操作员的错误,该操作员的右手操作数是类型' 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);
}
Code below, for my linked list implementation and specifically emplace_back below. What am I doing wrong and how to fix?
Error I am getting is:
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 implementation:
#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 to exercise:
#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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的问题是
node
正在尝试构造一个President
,但President
没有默认构造函数。您需要构造一个带有President
的node
,就像在这个构造函数中一样:因为
emplace_back
尝试就地构造一个对象,所以您'还需要添加一个构造函数来使用传入的参数构造value
。最后,更新您的
emplace_back
函数以在构造时转发参数。这是用 gcc 和 clang 为我编译的。
Your issue is that
node
is trying to construct aPresident
, butPresident
doesn't have a default constructor. You'll need to construct anode
with aPresident
, like in this constructor:Because
emplace_back
tries to construct an object in place, you'll also need to add a constructor to constructvalue
using the arguments that are passed in.Lastly, update your
emplace_back
function to forward arguments at construction time.This is compiling for me with gcc and clang.
问题(如错误中所述)是:
list :: node :: node :: node()
没有默认构造函数,因为它是 隐式删除 。总统
没有默认的构造函数,因为您用户定义的构造函数总统
,因此编译器将不合成您的默认构造函数。没有
operator =
总统
。到 solve 这些问题您需要添加以下内容:
node
喜欢node()= default()= default();
insemins
for
。node
节点总统
的默认构造函数类似总统()= default;
总统。总统
的分配操作员。The problems(as reflected in the errors) are:
There is no default constructor for
list::node::node()
because it is implicitly deleted.President
has no default constructor because you've user defined constructors forPresident
and so compiler will not synthesize the default constructor for you.There is no
operator=
forPresident
.To solve these problems you need to add the following things:
node
likenode() = default();
insidenode
.President
likePresident() = default;
insidePresident
.President
.