不能将std :: iota与std :: set一起使用

时间:2013-10-22 22:21:26

标签: c++ visual-c++ c++11 stl

我想创建一组数字:0,1,2,3,4 ...... 以下代码无法编译:

std::set<int> s;
std::iota(s.begin(), s.end(), 0);

出现以下错误消息:

error C3892: '_First' : you cannot assign to a variable that is const

编译器是VC ++ 2012。相同的代码适用于矢量。我应该如何使用它?

更新

我现在可以看到我的代码没有意义,因为没有指定设置大小。

以下是有关我的问题的更多详细信息。

我有一个包含[0,N]范围内某些数字的集合。在我的应用程序中,我需要多次计算这些集合的集合差异。 N是固定的。

我们说N = 5,第一组是s1 = {0, 3, 4}。我需要计算集合差异{0, 1, 2, 3, 4} \ {0, 3, 4} == {1, 2}。对于不同的集合,应该经常执行此操作,因此我认为我可以创建一个包含所有数字的集合(在这种情况下为{0, 1, 2, 3, 4})并使用std::set_difference来计算这些差异。

3 个答案:

答案 0 :(得分:12)

要解决您的实际问题,std::set_differencestd::set的关联程度低于您的预期。您可以使用任意一对迭代器作为set_difference的前两个参数,前提是它们按顺序返回值。作为一套,没有特别的好处。

因此,例如,包含值0 ... n-1的std::vector的开始/结束迭代器将按顺序工作,或者是一对boost::counting_iterator

std::set result;
std::set_difference(
    boost::counting_iterator<int>(0), boost::counting_iterator<int>(n),
    s1.begin(), s1.end(),
    std::inserter(result, result.end())
);

输出也不需要设置,您也可以vector使用back_inserter

要解决您的问题:尝试在集合上使用iota没有意义。 iota通过为其指定新值来更改范围中包含的值。您无法分配set

中的值

如果您想要一个包含数字0 ... n-1的集合,那么:

std::set<int> s;
for (int i = 0; i < n; ++i) {
    s.insert(s.end(), i);
}

如果有人告诉你循环是为了wusses而真正的C ++程序员使用算法,那么如果你真的想要你可以参与iota

std::set<int> s;
{
    std::vector<int> vec(n);
    std::iota(vec.begin(), vec.end(), 0);
    s.insert(vec.begin(), vec.end());
}

不幸的是,这种效率低下。因此,如果您非常喜欢算法,以至于您可以将它们结合起来,那么您可以到达标准库之外:

std::set<int> s(boost::counting_iterator<int>(0), boost::counting_iterator<int>(n));

答案 1 :(得分:2)

略显不雅的选择:

set<int> s;
generate_n(inserter(s, s.end()), 10, [&]{ return s.size(); });

答案 2 :(得分:1)

集合与向量的不同之处在于向量具有从索引到存储在该索引处的值的关联,而集合仅具有值是否在集合中的信息。因此,为set元素赋值是没有意义的 - 强制执行它的方法是集合中的元素是常量。

执行此操作的等效方法类似于删除集合中不需要的值(在向量的情况下为“旧”值),然后遍历要存储的值(使用itoa)它将是一个递增值的序列)并将它们逐个添加到集合中。