0

Recently, i learnt about the STL types and templates and we were given a challenge as part of practicing the STL and getting used to using it:

  1. Iterate over a std::map<std::string, size_t>
  2. Print its contents

Restrictions:

  1. Can only use: std::vector, std::map, std::string, std::algorithm, std::functional

  2. Cannot define complex types nor templates

  3. Cannot use the . (member access), -> (member access via pointer), * (dereference) operators

  4. Cannot use for, while, do-while nor if-else, switch and other conditionals

  5. Can use std::for_each and other functions of function templates to iterate over collection of elements

  6. No lambdas

  7. No std::cout, std::cerr, std::ostream etc.

  8. No auto types

  9. Can use other STL templates so long as they are included in the headers described at (1)

Allowed to use these functions:

void print(const std::string& str)
{
    std::cout << str << std::endl;
}
std::string split(const std::pair<std::string, size_t> &r)
{
    std::string name;
    std::tie(name, std::ignore) = r;
    return name;
}

Originally, i had wanted to use std::for_each(std::begin(mymap), std::end(mymap), print) to iterate over the map and then use the print function to print out the contents. Then i realised that i am actually working with std::pair<std::string, size_t> which made me consider the use of std::bind and std::tie to break the std::pair up. But since i THINK i need to do it inside the std::for_each expression, how can i break up the std::pair while also call print on the elements?

I have also considered using Structured Binding but i am not allowed to use auto.

So, the question is, how do i make use of the STL to iterate the map to extract then print out the keys using the helper functions provided? Obviously, without the restrictions the challenge would have been very easy, but i am at a loss as to what kind of functions in the STL are appropriate in light of this.

bolov
  • 72,283
  • 15
  • 145
  • 224
eglades
  • 77
  • 8
  • 2
    most of these restrictions seem kind of random. – bolov Nov 30 '19 at 19:36
  • also I think you mean "The Standard Library" instead of STL https://stackoverflow.com/questions/5205491/whats-the-difference-between-stl-and-c-standard-library – bolov Nov 30 '19 at 19:39
  • 1
    `std::for_each(m.begin(),m.end(),std::bind(print,std::bind(split,std::placeholders::_1)));` this line prints all keys, where `m` is your map. [Demo](https://godbolt.org/z/YrTHXB). Because `std::bind` comes from `functional`, this code satisfies your requirements. – rafix07 Nov 30 '19 at 19:44
  • @rafix07 Thank you. This solution is elegant and has helped me appreciate std::bind a lot – eglades Dec 01 '19 at 06:57

1 Answers1

0

I used from your function that takes a "std::pair& as for_each third argument.

I use printf() for print values.

#include <string>
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;


std::string Split(const std::pair<std::string, size_t> &r)
{
    std::string name;
    std::tie(name, std::ignore) = r;
    return name;
}

int main()
{
    string name1{ "John" };
    string name2{ "Jack" };

    std::map<std::string, size_t> sample = { {name1, 31}, {name2, 35} };
    static vector<std::string> names;

    std::for_each(sample.begin(), sample.end(), [](std::pair<std::string, size_t> pickup)
    {
        static int i = 0;
        names.push_back(Split(pickup));
        printf("%s\n", names[i].c_str());
        i++;
    });

}