我喜欢基于范围的is_last_elem
测试。恕我直言,它非常易读:
for (auto& e : range)
{
if (!is_last_elem(e, range)) [[likely]]
os << e << ", ";
else
os << e;
}
os << std::endl;
完整代码:
C++20:
#include <iostream>
#include <list>
#include <ranges>
#include <utility>
#include <type_traits>
#include <memory>
template <std::ranges::bidirectional_range R>
bool is_last_elem(const std::ranges::range_value_t<R>& elem, const R& range)
{
auto last_it = range.end();
std::advance(last_it, -1);
return std::addressof(elem) == std::addressof(*last_it);
}
template <std::ranges::bidirectional_range R, class Stream = std::ostream>
void print(const R& range, std::ostream& os = std::cout)
{
for (auto& e : range)
{
if (!is_last_elem(e, range)) [[likely]]
os << e << ", ";
else
os << e;
}
os << std::endl;
}
int main()
{
std::list<int> v{1, 2, 3, 4, 5};
print(v);
}
C++17:
#include <iostream>
#include <list>
#include <utility>
#include <type_traits>
#include <memory>
template <class Range>
using value_type_t = std::remove_reference_t<decltype(*std::begin(std::declval<Range>()))>;
template <class Range>
bool is_last_elem(const value_type_t<Range>& elem, const Range& range)
{
auto last_it = range.end();
std::advance(last_it, -1);
return std::addressof(elem) == std::addressof(*last_it);
}
template <class Range, class Stream = std::ostream>
void print(const Range& range, std::ostream& os = std::cout)
{
for (auto& e : range)
{
if (!is_last_elem(e, range))
os << e << ", ";
else
os << e;
}
os << std::endl;
}
int main()
{
std::list<int> v{1, 2, 3, 4, 5};
print(v);
}