Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;具有与Python相同功能的工具';s过滤器和映射 Python编程语言,我在寻找一个C++代码类似的代码:< map > 或过滤器>代码>。第一个函数将某些函数应用于iterable的每一项并返回结果列表,第二个函数从iterable的元素构造一个列表,该函数为其返回true_Python_C++_Boost_Functional Programming - Fatal编程技术网

C++;具有与Python相同功能的工具';s过滤器和映射 Python编程语言,我在寻找一个C++代码类似的代码:< map > 或过滤器>代码>。第一个函数将某些函数应用于iterable的每一项并返回结果列表,第二个函数从iterable的元素构造一个列表,该函数为其返回true

C++;具有与Python相同功能的工具';s过滤器和映射 Python编程语言,我在寻找一个C++代码类似的代码:< map > 或过滤器>代码>。第一个函数将某些函数应用于iterable的每一项并返回结果列表,第二个函数从iterable的元素构造一个列表,该函数为其返回true,python,c++,boost,functional-programming,Python,C++,Boost,Functional Programming,我想在C++中使用类似的功能: 将一些函数映射到容器,以便获得具有转换数据(可能具有不同长度)的新容器 对容器使用某种条件筛选 < P>在C++中,有没有Python的映射和过滤器的精细实现? 在这个简短的例子中,我试图使用诸如boost::bind和std::for_等工具来解决这个问题,我面临着一个困难。std::vector结果应包含所有按字典顺序高于stdin中最后一个字符串的字符串std::vector raw。但事实上,结果容器在返回点仍然是空的 #include <ios

我想在C++中使用类似的功能:

  • 将一些函数映射到容器,以便获得具有转换数据(可能具有不同长度)的新容器
  • 对容器使用某种条件筛选
< P>在C++中,有没有Python的映射和过滤器的精细实现? 在这个简短的例子中,我试图使用诸如
boost::bind
std::for_等工具来解决这个问题,我面临着一个困难。
std::vector结果
应包含所有按字典顺序高于stdin中最后一个字符串的字符串
std::vector raw
。但事实上,
结果
容器在返回点仍然是空的

#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>

void filter_strings(std::string& current, std::string& last, std::vector<std::string>& results)
{
    if (current > last)
    {
        results.push_back(current);
        std::cout << "Matched: " << current << std::endl;
    }
}

int main()
{
    std::vector<std::string> raw, result;
    std::string input, last;

    //Populate first container with a data
    while(std::getline(std::cin, input))
        raw.push_back(input);
    last = raw.back();

    //Put into result vector all strings which lexicographically higher than the last one
    std::for_each(raw.begin(), raw.end(), boost::bind(&filter_strings, _1, last, result));

    //For some reason the resulting container is empty
    std::cout << "Results: " << result.size() << std::endl;

    return 0;
}

任何帮助都将不胜感激。

正如@juanchopanza所建议的那样,
STL标题中的模板函数是您最好的选择

#include <iostream>
#include <vector>


std::vector<std::string> filter(std::vector<std::string> & raw) {
    std::vector<std::string> result(raw.size());
    std::string last = raw[raw.size() - 1];
    auto it = std::copy_if(raw.begin(), raw.end(), result.begin(),
        [&](std::string s) { return s.compare(last) > 0; });
    result.resize(std::distance(result.begin(), it));
    return result;
}

int main(int argc, const char *argv[])
{
    std::vector<std::string> raw, result;
    std::string input;
    while (std::getline(std::cin, input)) {
        raw.push_back(input);
    }

    result = filter(raw);

    for (size_t i = 0; i < result.size(); i++) {
        std::cout << "Matched: " << result[i] << std::endl;
    }
    std::cout << "Results: " << result.size() << std::endl;
    return 0;
}

代码未按预期工作的原因是
bind()
复制了所有参数。这意味着您正在将项添加到
std::vector结果的副本中
要解决此问题,需要将向量放入引用包装器中。然后会被复制,但它包含对
结果的引用。变化很小:

std::for_each(raw.begin(), raw.end(), std::bind(&filter_strings, std::placeholders::_1, last, std::ref(result)));
注意,这里我使用的是C++11绑定,而不是boost绑定

现在,如果要使用lambda将谓词代码保持在筛选器的本地,可以:

std::for_each(raw.begin(), raw.end(), [&](std::string& s){ if (s > last) result.push_back(s); });
或者使用
std::copy\u,如果

std::copy_if(raw.begin(), raw.end(), std::back_inserter(result), [&](std::string& s){ return s > last; });

要使当前代码正常工作,必须将
result
参数包装到
boost::bind
内部
boost::ref()
,否则
bind
将复制您的结果

除此之外,胡安科潘扎和阿列克斯布松的评论员已经对此给出了很好的回答

使用普通的C++11标准库(即不使用Boost),您可以通过将
std::for_each()
替换为以下内容来实现上述程序(请注意,
filter_strings
函数不再需要了,您需要为
std::back_inserter
):

std::copy_if(raw.begin()、raw.end()、std::back_插入器(result),
[&](标准::字符串常量和当前值)->bool{
如果(当前>上次)
{

std::看不见,你需要为在std容器上工作的好的泛型
map
filter
函数编写一些非常糟糕的模板,我试过一次,但失败了。相反,你应该使用@juanchopanza建议的
std::algorithm
。看看boost range,它导致的代码非常类似于linq和python
std::for_each(raw.begin(), raw.end(), [&](std::string& s){ if (s > last) result.push_back(s); });
std::copy_if(raw.begin(), raw.end(), std::back_inserter(result), [&](std::string& s){ return s > last; });
std::copy_if(raw.begin(), raw.end(), std::back_inserter(result),
    [&](std::string const& current) -> bool {
        if (current > last)
        {
            std::cout << "Matched: " << current << std::endl;
            return true;
        }
        return false;
    }
);