[英]Can range-based for loops be aware of the end?
給出最小的C ++ 11 STL示例:
set<int> S = {1,2,3,4};
for(auto &x: S) {
cout << x;
cout << ",";
}
有沒有辦法檢查x
是否在結束之前? 此示例中的目標是輸出1,2,3,4
而不是最后的最后一個逗號。 目前我使用帶有兩個迭代器的標准for循環,
set<int>::const_iterator itr;
set<int>::const_iterator penultimate_end_itr = --S.end();
for(itr=S.begin(); itr!=penultimate_end_itr;++itr)
cout << (*itr) << ',';
cout << (*penultimate_end_itr);
哪個有效,但非常麻煩。 有沒有辦法在基於范圍的for循環中進行檢查?
編輯:問題的關鍵是不打印逗號分隔列表。 我想知道基於范圍的for循環是否具有列表中倒數第二個元素的任何知識(即它是在結束之前的一個)。 提出了最小的例子,所以我們都有一個共同的代碼塊來討論。
基於范圍的for循環的目的是忘記迭代器。 因此,它們只允許您訪問當前值而不是迭代器。 以下代碼會為您執行此操作嗎?
set<int> S = {1,2,3,4};
std::string output;
for(auto &x: S) {
if (!output.empty())
output += ",";
output += to_string(x);
}
cout << output;
編輯
另一個解決方案:您可以比較值的地址,而不是比較迭代器(就像循環的“正常”)。
set<int> S = {1,2,3,4};
auto &last = *(--S.end());
for (auto &x : S)
{
cout << x;
if (&x != &last)
cout << ",";
}
Boost.Range可以在這里提供幫助:
if (std::begin(S) != std::end(S)) {
std::cout << *std::begin(S);
for (const auto &x: boost::make_iterator_range(std::next(std::begin(S)), std::end(S))) {
std::cout << ", " << x;
}
}
一種更靈活的方法是使用boost::adaptors::indexed
(自Boost 1.56起) boost::adaptors::indexed
范圍:
for (const auto &element: boost::adaptors::index(S)) {
std::cout << (element.index() ? ", " : "") << element.value();
}
在1.56之前的Boost版本中,boost boost::adaptors::indexed
將不起作用,但您可以輕松編寫類似的工作:
template <typename... T>
auto zip(const T&... ranges) -> boost::iterator_range<boost::zip_iterator<decltype(boost::make_tuple(std::begin(ranges)...))>>
{
auto zip_begin = boost::make_zip_iterator(boost::make_tuple(std::begin(ranges)...));
auto zip_end = boost::make_zip_iterator(boost::make_tuple(std::end(ranges)...));
return boost::make_iterator_range(zip_begin, zip_end);
}
template<typename T>
auto enumerate(const T &range) -> boost::iterator_range<boost::zip_iterator<boost::tuple<
boost::counting_iterator<decltype(boost::distance(range))>, decltype(std::begin(range))>>>
{
return zip(boost::make_iterator_range(boost::make_counting_iterator(0),
boost::make_counting_iterator(boost::distance(range))), range);
}
for (const auto &tup: enumerate(S)) {
std::cout << (tup.get<0>() ? ", " : "") << tup.get<1>();
}
這是使用zip
從功能的C ++ 11序列-zip函數?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.