C++通用插入到标准容器中
C++ generic insert into std container?
如果我有以下程序:
#include <vector>
#include <set>
template<class T, class U>
void AddToContainer(T& container, U value)
{
container.push_back(value);
}
int main(char**, int)
{
std::vector<int> v;
AddToContainer(v, 1);
std::set<int> s;
AddToContainer(s, 1);
return 0;
}
如何使添加到容器的通用性?由于std::set
没有push_back
,只有insert
,这将无法编译。
您可以使用表达式 SFINAE 和虚拟参数来检查push_back()
是否有效:
template <class C, class V>
auto append(C& container, V&& value, int)
-> decltype(container.push_back(std::forward<V>(value)), void())
{
container.push_back(std::forward<V>(value));
}
template <class C, class V>
void append(C& container, V&& value, ...)
{
container.insert(std::forward<V>(value));
}
您的函数将转发到:
template <class C, class V>
void AddToContainer(C& container, V&& value) {
append(container, std::forward<V>(value), 0);
}
如果 push_back()
是有效的表达式,则首选第一个重载,因为int
比...
更适合0
如果push_back()
不是有效的表达式,则只有一个可行的重载。
这是否真的是一个好主意是一个单独的问题。
我相信
所有*C++容器(尽管不是像priority_queue
这样的容器适配器)都有一个如下所示的插入版本:
iterator insert(iterator location, T&& value)
对于序列集合,位置是实际位置;对于关联集合(如map
和unordered_map
),迭代器是一个"提示"参数(例如,如果您已经确切地知道元素在排序顺序中的位置,则帮助map
快速插入元素)。但是,提供无效提示不会导致任何无效行为,因此C++集合的有效泛型插入为:
template<C, T>
void insert(C& collection, T&& value) {
collection.insert(collection.end(), std::forward<T>(value));
}
*看起来forward_list
是唯一没有这种方法的人,这是有道理的。
C++20 样式:
template<typename C, typename V>
requires requires (C& c, V&& v) { c.push_back(std::forward<V>(v)); }
auto AddToContainer(C& container, V&& value) {
return container.push_back(std::forward<V>(value));
}
template<typename C, typename V>
requires (requires (C& c, V&& v) { c.insert(c.end(), std::forward<V>(v)); } &&
!requires(C& c, V&& v) { c.push_back(std::forward<V>(v)); })
auto AddToContainer(C& container, V&& value) {
return container.insert(container.end(), std::forward<V>(value));
}
或更简洁但诊断更差:
template<typename C, typename V>
auto AddToContainer(C& container, V&& value)
{
if constexpr (requires (C& c, V&& v) { c.push_back(std::forward<V>(v)); })
return container.push_back(std::forward<V>(value));
else
return container.insert(container.end(), std::forward<V>(value));
}
已经有一个(#include <iterator>
),但它的语法很奇怪:
std::inserter(container, container.end()) = value;
所有这一切都是在引擎盖下使用卢克莱蒂尔的答案,这仍然存在forward_list
缺乏insert
方法的问题。
如果您不担心集合中插入元素的顺序,
template<typename Container, typename value>
void addelement(Container& C, value v)
{
std::fill_n(std::inserter(C,C.end()), 1,v);
}
int main()
{
std::vector<int> v;
addelement(v, 2);
addelement(v, 4);
addelement(v, 6);
std::set<int> s;
addelement(s, 8);
addelement(s, 6);
addelement(s, 4);
addelement(s, 8);
std::cout << "Vector elements :: " << std::endl;
for (auto item : v)
std::cout << item << std::endl;
std::cout << "Set elements :: " << std::endl;
for (auto item : s)
std::cout << item << std::endl;
return 0;
}
相关文章:
- 将值插入到标准 c++ 数组的正确索引(升序)中
- 如何将元素插入到标准::地图的共享指针中?
- 无法插入到标准地图
- 如何将整数向量插入到键中,标准::映射的值
- 如何将标准::矢量插入具有自定义排序功能的 std::set 中
- 可以提示插入到标准::地图导致不平衡的树
- C++标准是否保证失败的插入到关联容器中不会修改 rvalue-reference 参数?
- 将标准::unique_ptr插入到提升:ptr_map
- 优化将标准::uint32_t插入到标准::向量<char>中
- 标准::unordered_map:插入何时失败
- 使用插入时自动调整标准::矢量的大小
- C++ 如何在标准::多映射中插入
- 插入到标准::字符串的向量,列表对
- C++通用插入到标准容器中
- C 标准委员会的目的是在C 11 Unordered_map中破坏其所插入的内容
- 将文件流插入到标准::映射
- 标准::TR1::unordered_map插入错误
- 为什么插入会使标准::设置反向迭代器无效
- 在标准::矢量与标准::插入上
- 有没有办法为符合标准的载体实现插入方法