1

I need to write a little function that makes a new std::set taking the last n elements from an existing one.

Here is the code:

template <typename S, typename T, typename Z>
std::set<T,S,Z> get_first_subset(std::set<T,S,Z> const& set, size_t size) {
    if (size == 0)
        return std::set<T,S,Z>();

    typename std::set<T,S,Z>::reverse_iterator j = set.rbegin();
    std::advance(j, size - 1);

    return std::set<T,S,Z> ((++j).base(), set.end());
}

It works, however since I do not need to access the type T, S, and Z I was wondering if there is a way to simply say "any std::set" without three template parameters.

Paolo.Bolzoni
  • 2,416
  • 1
  • 18
  • 29

1 Answers1

1

What about having it even more generic:

#include <iterator>
template <typename T>
T get_first_subset(T const& set, size_t size) {
  if (size == 0)
    return T();

  typename T::reverse_iterator j = set.rbegin();
  std::advance(j, size - 1);

  return T ((++j).base(), set.end());
}

Then:

int main() {
  std::set<int> s{10, 2,4,6,7,8,9}, s1;
  s1 = get_first_subset(s, 4);
  for (auto i:s1) std::cout << i << " ";
  std::cout << std::endl;
}

outputs:

7 8 9 10

You can also use variadic templates (C++11), brace initialization and auto keyword to avoid repeating yourself:

template <typename ...S>
std::set<S...> get_first_subset(std::set<S...> const& set, size_t size) {
  if (size == 0) return {};
  auto j = set.rbegin();
  std::advance(j, size - 1);
  return  {(++j).base(), set.end()};
}
hivert
  • 10,579
  • 3
  • 31
  • 56
  • Well, yes. I guess it works. Still I am curious if I can avoid all those template parameters when I want a specific standard data structure. – Paolo.Bolzoni Mar 04 '14 at 09:55
  • @Paolo.Bolzoni - you're concern about the usage or the function definition & signature? Because if it's the usage and you can use `C++11`, you can use `auto` and get something like (_not_ tested): `auto subset = get_first_subset( some_set, some_size );`. – Kiril Kirov Mar 04 '14 at 09:58
  • @Paolo.Bolzoni you can use variadic templates with C++11 to avoid specifying the several template parameters – piwi Mar 04 '14 at 09:58