有各種STL算法依賴輸出迭代器來存儲算法的結果。輸出迭代器適配器進行計數但不復制
例如,std::set_intersection
將在輸出迭代器中存儲兩個排序範圍之間的所有公共元素,然後每輸出一個元素後遞增。
有時,我對實際元素不感興趣,但只對輸出元素的數量感興趣。在這種情況下,複製元素會浪費內存和性能。有沒有可以用來計算和避免元素副本的迭代器適配器?如果不是,你能建議這樣一個適配器的通用實現嗎?
有各種STL算法依賴輸出迭代器來存儲算法的結果。輸出迭代器適配器進行計數但不復制
例如,std::set_intersection
將在輸出迭代器中存儲兩個排序範圍之間的所有公共元素,然後每輸出一個元素後遞增。
有時,我對實際元素不感興趣,但只對輸出元素的數量感興趣。在這種情況下,複製元素會浪費內存和性能。有沒有可以用來計算和避免元素副本的迭代器適配器?如果不是,你能建議這樣一個適配器的通用實現嗎?
由於很多從@ecatmur回答和評論的幫助下,我有以下的解決方案,我邀請評論。我曾希望得到boost::make_function_output_iterator
工作,但似乎有一個庫中的錯誤,無法定義賦值運算符。
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
#include <cassert>
class counting_output_iterator
{
public:
counting_output_iterator& operator=(const counting_output_iterator&) { return *this; };
explicit counting_output_iterator(std::size_t& count) : m_count(count) {}
template<typename T> void operator=(const T&) {}; //NULL op
using iterator_category = std::output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;
counting_output_iterator& operator*() { return *this; }
counting_output_iterator& operator++() { ++m_count; return *this; }
std::size_t& m_count;
};
int main(int, char*[])
{
std::vector<int> arr{ 1,2,3,4 };
std::size_t count = 0;
std::copy(std::begin(arr), std::end(arr), counting_output_iterator{ count });
assert(count == 4u);
return 0;
}
Boost的Function Output Iterator可以做你想做什麼:
std::size_t count = 0u;
int arr[]{0, 1, 2, 3};
std::copy(std::begin(arr), std::end(arr),
boost::make_function_output_iterator([&](auto const&) { ++count; }));
assert(count == 4u);
唯一的問題是,你必須聲明迭代器外的計數變量,因爲沒有辦法來提取一個boost::function_output_iterator
存儲函數對象(和也沒有辦法從lambda中提取閉包值,即使你超過了這個障礙)。如果你希望能夠編寫單行程序,你必須自己編寫迭代器類,但它不是大量的代碼;例如:
class counting_output_iterator {
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;
std::size_t value = 0u;
struct output_proxy {
output_proxy(std::size_t& value) : m_value(value) { }
template<class T> output_proxy& operator=(T const&) {
++m_value;
return *this;
}
std::size_t& m_value;
};
output_proxy operator*() { return output_proxy(value); }
counting_output_iterator& operator++() { return *this; }
counting_output_iterator& operator++(int) { return *this; }
};
用法:
int arr[]{0, 1, 2, 3};
auto const count = std::copy(std::begin(arr), std::end(arr),
counting_output_iterator{}).value;
assert(count == 4u);
投票關閉作爲資源的請求,但是您可能希望['提振:: counting_iterator'(http://www.boost.org/doc/libs/1_50_0/libs/iterator/doc/counting_iterator。 html) – NathanOliver
你的問題有點不清楚:你想知道有多少個元素將包含2個交集而沒有計算交集? – wasthishelpful
@wasthishelpful是的,在我的set_difference示例中,但我正在尋找一種適用於任何此類算法的通用Ouput迭代器解決方案。 – T33C