2

我有一个vector我想插入到set. 这是三个不同的调用之一(另外两个更复杂,涉及boost::lambda::if_()),但解决这个简单的案例将帮助我解决其他问题。

std::vector<std::string> s_vector;
std::set<std::string> s_set;
std::for_each(s_vector.begin(), s_vector.end(), s_set.insert(boost::lambda::_1));

不幸的是,这会失败并显示转换错误消息(尝试转换boost::lambda::placeholder1_typestd::string)。

所以……这有什么问题?

4

5 回答 5

3

该错误非常糟糕,但归结为它无法确定要使用哪个 set::insert ,因为存在三个重载。

您可以通过指定一个指向您希望使用的函数的指针来帮助 bind 帮助解决歧义:

typedef std::set<std::string> s_type;
typedef std::pair<s_type::iterator, bool>(s_type::*insert_fp)(const s_type::value_type&);
std::for_each(s_vector.begin(), s_vector.end(), boost::bind(static_cast<insert_fp>(&s_type::insert), &s_set, _1));

它不漂亮,但它应该工作。

于 2008-11-11T00:39:31.250 回答
2

我会使用一个for循环:-D

于 2008-11-11T01:00:24.623 回答
2

要将向量复制到集合中,可以使用 std::copy 和插入迭代器。就像是:

std::copy(s_vector.begin(), s_vector.end(), std::inserter(s_set, s_set.end()));

当然,这根本不使用 boost::lambda,因此它可能无法帮助您将其概括为做您想做的事情。最好更多地了解您在这里尝试做的事情。根据您对 lambda::_if 的提及,我将假设您的 lambda 将在插入集合之前对输入向量进行某种过滤。

以下(完整的,经过测试的)示例显示了如何仅将 <= 4 个字符的字符串从向量复制到集合中:

#include <boost/assign/list_of.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/test/minimal.hpp>

#include <set>
#include <vector>
#include <algorithm>

using namespace std;
using namespace boost::lambda;
using namespace boost::assign;

int test_main(int argc, char* argv[])
{
    vector<string> s_vector = list_of("red")("orange")("yellow")("blue")("indigo")("violet");
    set<string> s_set;

    // Copy only strings length<=4 into set:

    std::remove_copy_if(s_vector.begin(), s_vector.end(), std::inserter(s_set, s_set.end()),
                        bind(&string::length, _1) > 4u);

    BOOST_CHECK(s_set.size() == 2);
    BOOST_CHECK(s_set.count("red"));
    BOOST_CHECK(s_set.count("blue"));

    return 0;
}

希望这能给你一些东西吗?

还要让我重申上面的观点, boost::bind 和 boost::lambda::bind 是两种不同的野兽。从概念上讲,它们是相似的,但它们产生不同类型的输出。只有后者可以与其他 lambda 运算符结合使用。

于 2008-11-11T02:38:57.467 回答
1

我认为问题的一部分for_each()是期待一个仿函数,而您将函数调用的结果传递给它。因此,您的代码将vector<string>::insert()首先调用,然后将该调用的结果传递给for_each(). 我不确定确切的语法,但我认为您想在这里结合使用 bind 和 lambda 。例如

for_each(s_vector.begin(), s_vector.end(),
         boost::bind(set<string>::insert, s_set, boost::lambda::_1));
于 2008-11-11T00:20:09.480 回答
0

不幸的是,这:

std::for_each(s_vector.begin(), s_vector.end(),
        lambda::bind(&std::set<std::string>::insert, s_set, lambda::_1));

不起作用。(请注意,我使用了 set::insert,因为这就是 s_set 的含义。)该错误非常糟糕,但归结为它无法确定要使用哪个 set::insert,因为存在三个重载。我尝试使用的是返回 pair::iterator, bool> (插入值)的集合。显然,这是行不通的。

我注意到你使用了 boost::bind,而不是 boost::lambda::bind——这是故意的吗?(它们的工作方式似乎有些不同。)

我认为您期望函子而不是函数调用结果是正确的;我确信这可以变成函子,但我的大脑现在没有看到答案。

谢谢。

于 2008-11-11T00:34:17.047 回答