使用std :: for_each

时间:2019-11-30 19:04:24

标签: c++ stl c++17 stdbind

最近,我了解了STL类型和模板,在练习STL并习惯使用它的过程中,我们面临挑战:

  1. 遍历std::map<std::string, size_t>
  2. 打印其内容

限制:

  1. 只能使用:std::vectorstd::mapstd::stringstd::algorithmstd::functional

  2. 无法定义复杂类型或模板

  3. 无法使用. (member access), -> (member access via pointer), * (dereference) operators

  4. 不能使用for, while, do-while nor if-else, switch和其他条件

  5. 可以使用std::for_each和功能模板的其他功能来遍历元素集合

  6. 没有lambdas

  7. std::coutstd::cerrstd::ostream等。

  8. 没有自动类型

  9. 可以使用其他STL模板,只要它们包含在(1)中所述的标头中即可

允许使用以下功能:

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;
}

最初,我想使用std::for_each(std::begin(mymap), std::end(mymap), print)遍历地图,然后使用打印功能打印出内容。然后我意识到我实际上正在与std::pair<std::string, size_t>一起工作,这使我考虑使用std::bindstd::tie来分解std::pair。但是,由于我认为我需要在std::for_each表达式中执行此操作,因此我该如何分解std::pair并同时在元素上调用print?

我也考虑过使用Structured Binding,但是不允许我使用auto

所以,问题是,如何利用STL迭代地图以提取内容,然后使用提供的帮助程序功能打印出键?显然,没有限制,挑战本来就很容易,但是鉴于这一点,我对于STL中的哪种功能合适感到困惑。

2 个答案:

答案 0 :(得分:0)

我从您的函数中使用了一个“ std :: pair&作为for_each第三个参数”。

我使用printf()作为打印值。

#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++;
    });

}

答案 1 :(得分:0)

如果您不允许使用lambda,则可以改用仿函数。

#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <tuple>

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;
}

struct printName
{
    void operator()(const std::pair<std::string, size_t>& p)
    {
        print(split(p));
    }
};

int main()
{
    std::map<std::string, size_t> sample = { {"Peter", 31}, {"John", 35}, {"Sally", 29}, {"Jane", 38} };

    std::for_each(sample.begin(), sample.end(), printName());

    return 0;
}

工作版本: https://godbolt.org/z/qXZ5am