c++插入空向量不能使用大括号
c++ insert empty vector can not use braces
下面的代码不能正常工作,当我引用 it
时,它会导致 Member call on null pointer error
,如果不支持,为什么它允许使用 insert(end, {})
(没有编译错误).
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<vector<pair<int, int>>> vv;
auto it = vv.insert(vv.end(), {});
cout << it->size() << endl;
}
当我更改 {}
to vector<pair<int, int>>
时,没有错误显示并打印 0
.
通过评论解决,它调用iterator insert( const_iterator pos, std::initializer_list<T> ilist )
,因此将其更改为insert(end, {{}})
可以工作。
第 auto it = vv.insert(vv.end(), {});
行使用的格式是 iterator insert( const_iterator pos, std::initializer_list<T> ilist );
。
作为第 auto it = vv.insert(vv.end(), {});
行的 intlizer 列表没有元素,因此没有元素插入向量 vv
。
因为没有插入元素,所以it
和vv.end()
一样,不能引用。
插入后可以通过检查vv
的长度来验证。请参阅 sample code here 进行检查。
根据cppreference – std::vector<T,Allocator>::insert(),所有类型insert()
return第一个插入元素的迭代器或者没有插入时的插入位置。
在暴露 MCVE 的 OP 中:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<vector<pair<int, int>>> vv;
auto it = vv.insert(vv.end(), {});
cout << it->size() << endl;
}
行
auto it = vv.insert(vv.end(), {});
不使用
iterator insert( const_iterator pos, const T& value );
正如预期的那样,但是
iterator insert( const_iterator pos, std::initializer_list<T> ilist );
.
因此,插入了 0 个元素,insert()
return 是传递的 end()
迭代器。
所以,
cout << it->size() << endl;
访问end()
的内容,这是未定义的行为。
我制作了一个小样本来演示这一点:
#include <initializer_list>
#include <iostream>
#include <vector>
template <typename T>
struct Container: std::vector<T> {
using typename std::vector<T>::iterator;
using typename std::vector<T>::const_iterator;
iterator insert( const_iterator pos, const T& value )
{
std::cout << "insert single value\n";
return std::vector<T>::insert(pos, value);
}
iterator insert( const_iterator pos, std::initializer_list<T> ilist )
{
std::cout << "insert initializer list\n";
return std::vector<T>::insert(pos, ilist);
}
};
using namespace std;
int main() {
Container<vector<pair<int, int>>> vv;
auto it = vv.insert(vv.end(), {});
cout << /*it->*/vv.size() << endl;
}
输出:
insert initializer list
0
注:
我知道重载至少是一种糟糕的风格 std::vector
。
我这样做是为了展示所使用的函数调用(我不知道如何实现这一点)。
下面的代码不能正常工作,当我引用 it
时,它会导致 Member call on null pointer error
,如果不支持,为什么它允许使用 insert(end, {})
(没有编译错误).
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<vector<pair<int, int>>> vv;
auto it = vv.insert(vv.end(), {});
cout << it->size() << endl;
}
当我更改 {}
to vector<pair<int, int>>
时,没有错误显示并打印 0
.
通过评论解决,它调用iterator insert( const_iterator pos, std::initializer_list<T> ilist )
,因此将其更改为insert(end, {{}})
可以工作。
第 auto it = vv.insert(vv.end(), {});
行使用的格式是 iterator insert( const_iterator pos, std::initializer_list<T> ilist );
。
作为第 auto it = vv.insert(vv.end(), {});
行的 intlizer 列表没有元素,因此没有元素插入向量 vv
。
因为没有插入元素,所以it
和vv.end()
一样,不能引用。
插入后可以通过检查vv
的长度来验证。请参阅 sample code here 进行检查。
根据cppreference – std::vector<T,Allocator>::insert(),所有类型insert()
return第一个插入元素的迭代器或者没有插入时的插入位置。
在暴露 MCVE 的 OP 中:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<vector<pair<int, int>>> vv;
auto it = vv.insert(vv.end(), {});
cout << it->size() << endl;
}
行
auto it = vv.insert(vv.end(), {});
不使用
iterator insert( const_iterator pos, const T& value );
正如预期的那样,但是
iterator insert( const_iterator pos, std::initializer_list<T> ilist );
.
因此,插入了 0 个元素,insert()
return 是传递的 end()
迭代器。
所以,
cout << it->size() << endl;
访问end()
的内容,这是未定义的行为。
我制作了一个小样本来演示这一点:
#include <initializer_list>
#include <iostream>
#include <vector>
template <typename T>
struct Container: std::vector<T> {
using typename std::vector<T>::iterator;
using typename std::vector<T>::const_iterator;
iterator insert( const_iterator pos, const T& value )
{
std::cout << "insert single value\n";
return std::vector<T>::insert(pos, value);
}
iterator insert( const_iterator pos, std::initializer_list<T> ilist )
{
std::cout << "insert initializer list\n";
return std::vector<T>::insert(pos, ilist);
}
};
using namespace std;
int main() {
Container<vector<pair<int, int>>> vv;
auto it = vv.insert(vv.end(), {});
cout << /*it->*/vv.size() << endl;
}
输出:
insert initializer list
0
注:
我知道重载至少是一种糟糕的风格 std::vector
。
我这样做是为了展示所使用的函数调用(我不知道如何实现这一点)。