gpt4 book ai didi

c++ - 为什么类型推导对我的集合交集和集合差异调用不起作用?

转载 作者:行者123 更新时间:2023-11-30 01:38:32 26 4
gpt4 key购买 nike

我正在尝试编写一个小算法来查找两个集合的共同部分和独特部分,并且我想以通用的方式编写它,所以我有这个小例子:

#include "boost/tuple/tuple.hpp"
#include <set>

template <typename InputIt, typename Value = typename std::iterator_traits<InputIt>::value_type>
boost::tuple<std::set<Value>, std::set<Value>, std::set<Value>>
findUniqueAndCommon(InputIt fbegin, InputIt fend, InputIt sbegin, InputIt send)
{
std::set<Value> setL(fbegin, fend);
std::set<Value> setR(sbegin, send);

std::set<Value> uniqueInCatalog1;
std::set<Value> uniqueInCatalog2;
std::set<Value> commonInBoth;

std::set_difference(setL.begin(), setL.end(), setR.begin(), setR.end(), uniqueInCatalog1.begin());
std::set_difference(setR.begin(), setR.end(), setL.begin(), setL.end(), uniqueInCatalog2.begin());
std::set_intersection(setL.begin(), setL.end(), setR.begin(), setR.end(), commonInBoth.begin());
return{ uniqueInCatalog1, uniqueInCatalog2, commonInBoth };
}

int main()
{
std::set<int> x = {1, 2, 3};
std::set<int> y = {4, 2, 3};
findUniqueAndCommon<std::set<int>::iterator>(x.begin(), x.end(), y.begin(), y.end());

}

我的问题是为什么这个函数编译失败?我尝试了 gcc、clang 和 MSVC,但它们都失败了。可以在此处检查 Clang 的错误消息:
https://godbolt.org/g/gFZyzo

非常感谢。

最佳答案

原因是std::set的常用迭代器 - the one you get with begin() - 不适用于插入或删除,仅用于遍历集合中的内容。试试 std::inserter相反:

#include "boost/tuple/tuple.hpp"
#include <set>

template <typename InputIt, typename Value = typename std::iterator_traits<InputIt>::value_type>
boost::tuple<std::set<Value>, std::set<Value>, std::set<Value>>
findUniqueAndCommon(InputIt fbegin, InputIt fend, InputIt sbegin, InputIt send)
{
std::set<Value> setL(fbegin, fend);
std::set<Value> setR(sbegin, send);

std::set<Value> uniqueInCatalog1;
std::set<Value> uniqueInCatalog2;
std::set<Value> commonInBoth;

std::set_difference(setL.begin(), setL.end(), setR.begin(), setR.end(), std::inserter(uniqueInCatalog1, uniqueInCatalog1.end()));
std::set_difference(setR.begin(), setR.end(), setL.begin(), setL.end(), std::inserter(uniqueInCatalog2, uniqueInCatalog2.end()));
std::set_intersection(setL.begin(), setL.end(), setR.begin(), setR.end(), std::inserter(commonInBoth, commonInBoth.end()));
return{ uniqueInCatalog1, uniqueInCatalog2, commonInBoth };
}

int main()
{
std::set<int> x = {1, 2, 3};
std::set<int> y = {4, 2, 3};
findUniqueAndCommon<std::set<int>::iterator>(x.begin(), x.end(), y.begin(), y.end());
}

不过请注意:

  1. 您正在创建范围的集合拷贝;我不认为你真的需要那样做。只需使用范围 - set_differenceset_intersection 实际上适用于范围而不是集合。
  2. std::set 默认保持有序。您需要在运行此代码之前和之后订购它们吗?如果不是,请考虑选择不同的容器。另一方面,正如@n.m 指出的那样,set_differenceset_intersection 需要有序的容器。
  3. 您将对这两个集合进行三次迭代而不是一次(您可以使用自定义函数在有序容器上执行此操作)。
  4. C++ 标准有自己的元组 - std::tuple - 自 C++11 以来。

关于c++ - 为什么类型推导对我的集合交集和集合差异调用不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47621034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com