现在,我有下面的代码,它只是测试标准库中的< code>std::set_difference:
#include <algorithm>
#include <vector>
#include <memory>
#include <iostream>
struct Node{
public:
Node(int x) : foo(x){}
int foo = 10;
};
using NodePtrVec = std::vector<std::shared_ptr<Node>>;
using NodePtr = std::shared_ptr<Node>;
using IntVec = std::vector<int>;
int main(void){
// pointer test
NodePtr inA_1 = std::make_shared<Node>(1);
NodePtr inA_2 = std::make_shared<Node>(11);
NodePtr inA_3 = std::make_shared<Node>(111);
NodePtr inB_1 = std::make_shared<Node>(2);
NodePtr inB_2 = std::make_shared<Node>(22);
NodePtr inB_3 = std::make_shared<Node>(222);
NodePtr both_1 = std::make_shared<Node>(3);
NodePtr both_2 = std::make_shared<Node>(33);
NodePtrVec a{inA_1,inA_2,inA_3,both_1,both_2};
NodePtrVec b{inB_1,inB_2,inB_3,both_1,both_2};
NodePtrVec c{};
std::set_difference(a.begin(), a.end(), b.begin(), b.end(),
std::back_inserter(c));
for(const auto& tmp : c){
std::cout << tmp->foo << std::endl;
}
// int test
std::cout << "int test" << std::endl;
IntVec int_a = {1,5,4,2,3};
IntVec int_b = {1,10,7};
IntVec int_c;
std::set_difference(int_a.begin(), int_a.end(), int_b.begin(), int_b.end(),
std::back_inserter(int_c));
for(const auto& tmp : int_c){
std::cout << tmp << std::endl;
}
}
当我用Clang/GCC编译它时,我得到了输出:
ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
1
11
111
int test
5
4
2
3
更新我想实际使用的源代码案例(假设Node
是我将要做的一些操作。因此,这些操作将按总数
的顺序发生):
#include <algorithm>
#include <vector>
#include <memory>
#include <iostream>
struct Node{
public:
Node(int x) : foo(x){}
int foo = 10;
};
using NodePtrVec = std::vector<std::shared_ptr<Node>>;
using NodePtr = std::shared_ptr<Node>;
using IntVec = std::vector<int>;
int main(void){
// pointer test
NodePtr inA_1 = std::make_shared<Node>(1);
NodePtr inA_2 = std::make_shared<Node>(11);
NodePtr inA_3 = std::make_shared<Node>(111);
// total elements
NodePtrVec total{inA_1,inA_2,inA_3};
// sub set of the elements
NodePtrVec sub{inA_2};
NodePtrVec c{};
// just want to get the compliment of the sub in total
// as expected, c should be {inA_1,inA_3}
std::set_difference(total.begin(), total.end(), sub.begin(), sub.end(),
std::back_inserter(c));
for(const auto& tmp : c){
std::cout << tmp->foo << std::endl;
}
}
好吧,这看起来不错,它实际上对应于标准::set_difference,检查链接:但是当我选择MSVC时,我得到了不同的输出(检查链接:https://godbolt.org/z/nYre1Eono):
example.cpp
ASM generation compiler returned: 0
example.cpp
Execution build compiler returned: 0
Program returned: 0
1
11
111
3
33
int test
5
4
2
3
哎呀,我们得到了意想不到的结果!顺便说一下,当我更改MSVC编译器版本时,输出似乎会改变。但是为什么呢?
就像注释中提到的,在你的例子中< code>std::set_difference比较的是< code>shared_ptr,而不是指针指向的值。当然,它仍然可以工作,因为< code>std::shared_ptr有< code>operator==只比较原始指针的地址,但是set_difference的要求是对范围进行排序,如果您查看MSVC的输出,情况并非如此(看起来像是碰巧按升序分配了内存,这导致了排序的向量)。首先对向量进行排序:
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
在MSVC,你也会得到你想要的结果。或者更好的是,使用自定义比较器对向量进行排序,然后使用自定义比较器计算集合差,这样会更习惯:
std::sort(a.begin(), a.end(), [](auto lhs, auto rhs) { return lhs->foo < rhs->foo; });
std::sort(b.begin(), b.end(), [](auto lhs, auto rhs) { return lhs->foo < rhs->foo; });
std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c), [](auto lhs, auto rhs) {
return lhs->foo < rhs->foo;
});
编辑
我刚刚在评论中读到,你实际上想比较指针,而不是它们指向的值。在这种情况下,我的答案的第一部分是最相关的。
编辑2:
所以这些行为会按照总数的顺序发生
然后,您必须复制矢量,对其进行排序并计算差值,或者您不能在您的情况下使用std::set_difference
。如果需要保留操作的相对顺序,可以尝试以下操作:迭代 A 并将元素插入到 C 中(如果 B 中不存在)。由于只需要保留 A 中元素的顺序,因此对容器 B 使用 std::unordered_set
,因为它具有常量时间查找(平均):
NodePtrVec total{inA_1,inA_2,inA_3};
std::unordered_set<NodePtr> sub{inA_2};
NodePtrVec c{};
for (auto el : total)
{
if (sub.count(el) == 0)
{
c.push_back(el);
}
}
必须对输入到< code>set_difference的范围进行排序。你的没有分类。
我正在尝试实现ESAPI编码以防止在我的spring-mvc项目中进行XSS攻击。我的方法是在发送回响应中的输入之前,我将使用 ESAPI.encoder() 对其进行编码,以便在页面响应中对输入属性进行编码。 我的假设是,当我返回编码的响应时,在我的页面响应中,我将得到编码的字符,而在我的输入字段中,我会得到普通的字符,但我的输入域也设置了编码的字符。 下面是我在发送响应之前在控制器中编写的示例
问题内容: 给定相同的主要版本,例如Java 7,不同的Java编译器(例如Oracle的热点,JRockit或IBM的J9等)是否将给定的Java源代码文件编译为相同的bytcode? 扫描Java 7语言规范 ,似乎正在讨论的是语言的语义,而不是代码到字节码的转换。 YES 。 以上摘录为: JLS留下了许多实现细节,因一个实现而异。 和 但是,JLS没有指定从源代码到生成的字节码的1:1映射
我将json传递给ObjectMapper。JSON字符串如下所示: 我的类如下所示: 这种行为是意料之中的吗?如果是,有什么解决办法? 更新:添加了类描述。
考虑下面这个简短的C++程序: 如果我在不同的编译器上编译它,我会得到不同的结果。对于CLANG3.4和GCC 4.4.7,它打印,而Visual Studio 2013打印,这意味着它们在调用不同的强制转换操作符。根据标准,哪一个是正确的行为? 根据我的理解,不需要转换,而需要到的转换,因此编译器应该选择第一个。对此做了什么吗?const-conversion是否被编译器认为更“昂贵”? 如果删
上面的代码使用不同的编译器会有不同的结果。这是编译器的错误还是我漏掉了什么? 叮叮当当 1 1 (https://godbolt.org/z/s43T55rxq) msvc 1 1 (https://godbolt.org/z/YnKfKh41q) 全球循环 0 1 (https://godbolt.org/z/91xdfv93c)
问题内容: 我需要获取UNIX时间戳(字符串),将其转换为特定格式的日期,并将其存储在DATETIME列的MySQL数据库中。 这是我的代码(简化): 控制台输出: 当我尝试在MySQL数据库中推送此值时,它将引发Invalid DateError。 只是感到困惑,并以不同的格式显示时间戳。 问题答案: 不要将日期作为字符串传递给MySQL数据库。更好,更容易,更安全地传递日期对象。一方面,它可以