用于展平矢量向量的 c++ 模板函数
c++ Template function to flatten a vector of vector
我写了一个模板函数来展平向量的两个级嵌套向量。然而,第二级向量可以是另一个向量,unique_ptr向量,或shared_ptr向量。
例如:
std::vector<std::unique_ptr<std::vector<int>>> f1;
std::vector<std::shared_ptr<std::vector<int>>> f2;
std::vector<std::vector<int>> f3;
std::vector<std::unique_ptr<std::vector<std::string>>> f4;
std::vector<std::shared_ptr<std::vector<std::string>>> f5;
std::vector<std::vector<std::string>> f6;
我写了这段代码,可以在 coliru 上工作
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
#include <iostream>
#include <sstream>
template<typename T>
const T* to_pointer(const T& e) {
return &e;
}
template<typename T>
const T* to_pointer(const std::unique_ptr<T>& e) {
return e.get();
}
template<typename T>
const T* to_pointer(const std::shared_ptr<T>& e) {
return e.get();
}
template <typename T, typename K,
typename = typename std::enable_if<
std::is_same<K, std::unique_ptr<std::vector<T>>>::value or
std::is_same<K, std::shared_ptr<std::vector<T>>>::value or
std::is_same<K, std::vector<T>>::value
>::type
>
std::vector<T> flatten(std::vector<K>& source) {
std::vector<T> result;
size_t size = 0;
for (const auto& e : source) {
size += to_pointer(e)->size();
}
result.reserve(size);
for (const auto& e : source) {
auto ptr = to_pointer(e);
auto begin = ptr->begin();
auto end = ptr->end();
std::copy(begin, end, std::back_inserter(result));
}
return result;
}
但是,想检查是否有更好的方法来编写相同的代码。感谢您的时间和精力。
如果您希望简化代码,可以将std::accumulate
与自定义操作一起使用,如下所示:
#include <vector>
#include <numeric>
int main() {
std::vector<std::vector<int>> foo {
{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }
};
auto bar = std::accumulate(foo.begin(), foo.end(), decltype(foo)::value_type{},
[](auto& dest, auto& src) {
dest.insert(dest.end(), src.begin(), src.end());
return dest;
});
}
我的例子的缺点是它不会为新元素保留空间,而是在必要时重新分配它。
我的第一个示例仅适用于具有成员类型value_type
具有成员函数insert
的类型。这意味着foo
不能是例如std::vector<std::unique_ptr<std::vector<int>>>
。
上述问题可以通过在两个函数模板上使用 SFINAE 来解决,如下所示:
template<typename T, typename = typename T::value_type>
T flatten(const std::vector<T>& v) {
return std::accumulate(v.begin(), v.end(), T{}, [](auto& dest, auto& src) {
dest.insert(dest.end(), src.begin(), src.end());
return dest;
});
}
template<typename T, typename = typename T::element_type::value_type>
typename T::element_type flatten(const std::vector<T>& v) {
using E = typename T::element_type;
return std::accumulate(v.begin(), v.end(), E{}, [](auto& dest, auto& src) {
dest.insert(dest.end(), src->begin(), src->end());
return dest;
});
}
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗