如何将Back_inserter与转换组合C 相结合
How to combine back_inserter with a transformation, C++
如何通过转换将输出仪(例如back_inserter_iterator
(包装?考虑
std::vector<double> xx;
std::vector<double> yy;
std::vector<double> diff;
auto ba = std::back_inserter(diff);
std::set_difference(xx.begin(), xx.end(), yy.begin(), yy.end(), ba);
我想在推回DIFF向量之前应用免费功能f(double)
或g(std::vector<double>::iterator)
:
具体来说,我如何存储差异元素(或迭代器(的地址,而不是元素主题。
std::vector<double&> diff;
auto baAdr = ??? std::back_inserter( ??? (diff));
std::set_difference(xx.begin(), xx.end(), yy.begin(), yy.end(), baAdr);
出于性能原因(实际数据很大(,我不想从中构建临时向量和std::transform
。它也不适用于不可仿制的可移动类型。
我可以使用boost。
with boost::function_output_iterator
:
#include <vector>
#include <algorithm>
#include <boost/function_output_iterator.hpp>
int main()
{
std::vector<double> xx;
std::vector<double> yy;
std::vector<const double*> diff; // const pointers, or else you
// need a const_cast in lambda
std::set_difference(xx.begin(), xx.end(), yy.begin(), yy.end(),
boost::make_function_output_iterator(
[&diff](const double& d) { diff.push_back(&d); }
)
);
}
可能内置了一些可以提升的东西,但是这是我编写自己的迭代器的骇人听闻的尝试:
template <typename T, typename FN>
struct transform_iterator {
transform_iterator(T &t, FN fn)
: _t{t}
, _fn{std::move(fn)} { }
transform_iterator<T, FN>& operator * () { return *this; }
transform_iterator<T, FN>& operator ++ () { return *this; }
template <typename V>
transform_iterator<T, FN>& operator = (V const &v) {
_t.push_back(_fn(v));
return *this;
}
T &_t;
FN _fn;
};
这将在尝试分配给迭代器时执行功能并执行它(i think 这就是诸如back_inserter
之类的事情通常工作的方式(。琐碎的辅助功能可以创建迭代器:
template <typename T, typename FN>
auto make_transform_iterator(T &t, FN fn) {
return transform_iterator<T, FN>{t, std::move(fn)};
};
最后,iterator_traits
需要专业化,因此transform_iterator
将使用算法。
namespace std {
template <typename T, typename FN>
struct iterator_traits<transform_iterator<T, FN>> {
using value_type = typename T::value_type;
};
}
在iterator_traits
中需要设置更多类型,但这足以进行我的测试。您的里程会有所不同。
我的main
看起来像这样:
int main() {
std::vector<int> xx{1, 2, 3};
std::vector<int> yy{1, 3, 5};
std::vector<int> diff;
auto ba = make_transform_iterator(diff, [](auto v) { return v + 10; });
std::set_difference(std::begin(xx), std::end(xx),
std::begin(yy), std::end(yy),
ba);
for(auto const &v: diff) {
std::cout << v << 'n';
}
return 0;
}
您可以将其扩展到使用通用输出迭代器而不是支持push_back
的类型。
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 处理将 AoS 转换为 SoA 时的组合爆炸
- 如何将Back_inserter与转换组合C 相结合
- 将字符串转换为带有Isringstream的字符和INT(组合)
- 编写饱和转换运算符而不列出所有可能的组合
- 如何使用for_each,transform,Iterator和lambda的某种组合将STD ::集合的字符串转换为小
- 从字符串转换时,如何组合多个枚举
- 从二十二个组合转换为十进制
- 如何将查找组合的几个循环代码转换为递归方法
- 布尔值转换为字符串,并将boolalpha与一个方法组合在一起,而不是在打印时单独键入它
- 将文件中的两个十六进制字符组合并转换为十进制