arm64 debian 上的 gcc-8 是否会忽略友元运算符<?
Does gcc-8 on arm64 debian ignores friend operator<?
我想比较两组对象。对于相同的代码,我在不同的机器上得到 2 个不同的输出。
该代码是用两个不同的编译器编译的。在 x86-64 机器上,我使用 gcc-11,在 aarch64 (raspberry pi4) 我使用的机器 gcc-8。我必须在 raspberry 上使用 gcc-8 因为它在官方存储库中。
有人知道为什么会这样吗?我错过了什么吗?
#include <iostream>
#include <set>
#include <memory>
class ClassA {
private:
::std::string id;
public:
explicit ClassA(::std::string id);
[[nodiscard]] ::std::string getId() const;
bool friend operator<(const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs);
};
ClassA::ClassA(::std::string id) : id{::std::move(id)} {}
::std::string ClassA::getId() const { return id; }
bool operator<(const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs) {
auto r = (lhs->id < rhs->id);
::std::cout << ::std::boolalpha << "Comparing lhs->id " << lhs->id << ", with rhs->id " << rhs->id
<< ". The result is " << r << ::std::endl;
return (lhs->id < rhs->id);
}
class ClassB {
public:
::std::set<::std::shared_ptr<ClassA>> members;
void add(::std::shared_ptr<ClassA> a);
};
void ClassB::add(::std::shared_ptr<ClassA> a) {
members.emplace(::std::move(a));
}
int main() {
::std::cout << "Create first set:" << ::std::endl;
auto firstContainer = ::std::set<::std::shared_ptr<ClassA>>{::std::make_shared<ClassA>("_3"),
::std::make_shared<ClassA>("_5")};
::std::cout << "Create second set:" << ::std::endl;
auto secondContainer = ::std::set<::std::shared_ptr<ClassA>>{::std::make_shared<ClassA>("_5"),
::std::make_shared<ClassA>("_3")};
auto b1 = ::std::make_shared<ClassB>();
auto b2 = ::std::make_shared<ClassB>();
::std::cout << "Fill first ClassB instance:" << ::std::endl;
for (const auto &r: firstContainer) {
b1->add(r);
}
::std::cout << "Fill second ClassB instance:" << ::std::endl;
for (const auto &r: secondContainer) {
b2->add(r);
}
auto result = ::std::equal(b1->members.begin(), b1->members.end(), b2->members.begin(),
[](const ::std::shared_ptr<ClassA> lhs, ::std::shared_ptr<ClassA> rhs) -> bool {
return lhs->getId() == rhs->getId();
});
::std::cout << ::std::boolalpha << "The result is: " << result << ::std::endl;
::std::cout << "First ClassB members" << ::std::endl;
for (const auto &r: b1->members) {
::std::cout << "Id " << r->getId() << ::std::endl;
}
::std::cout << "Second ClassB members" << ::std::endl;
for (const auto &r: b2->members) {
::std::cout << "Id " << r->getId() << ::std::endl;
}
return 0;
}
x86-64 输出。
Create first set:
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _5, with rhs->id _3. The result is false
Create second set:
Comparing lhs->id _5, with rhs->id _3. The result is false
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _3, with rhs->id _5. The result is true
Fill first ClassB instance:
Comparing lhs->id _5, with rhs->id _3. The result is false
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _5, with rhs->id _3. The result is false
Fill second ClassB instance:
Comparing lhs->id _5, with rhs->id _3. The result is false
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _5, with rhs->id _3. The result is false
The result is: true
First ClassB members
Id _3
Id _5
Second ClassB members
Id _3
Id _5
aarch64输出:
Create first set:
Create second set:
Fill first ClassB instance:
Fill second ClassB instance:
The result is: false
First ClassB members
Id _3
Id _5
Second ClassB members
Id _5
Id _3
问题在这里:
bool operator<(const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs)
共享指针有它自己的 comparison operators which compares stored pointers. There is also owner_less 比较 owned 指针(一个特殊构造的共享指针可以拥有一个对象但指向另一个对象,例如它可以指向拥有对象的成员)。
如果你需要比较指向的对象,你应该写一个 comparator 这样做,并将它作为第二个模板参数传递给集合。喜欢:
struct my_ClassA_id_less {
bool operator() (const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs) {
// your comparison code here, as for operator<
}
};
::std::set<std::shared_ptr<ClassA>, my_ClassA_id_less> my_set;
我想比较两组对象。对于相同的代码,我在不同的机器上得到 2 个不同的输出。 该代码是用两个不同的编译器编译的。在 x86-64 机器上,我使用 gcc-11,在 aarch64 (raspberry pi4) 我使用的机器 gcc-8。我必须在 raspberry 上使用 gcc-8 因为它在官方存储库中。
有人知道为什么会这样吗?我错过了什么吗?
#include <iostream>
#include <set>
#include <memory>
class ClassA {
private:
::std::string id;
public:
explicit ClassA(::std::string id);
[[nodiscard]] ::std::string getId() const;
bool friend operator<(const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs);
};
ClassA::ClassA(::std::string id) : id{::std::move(id)} {}
::std::string ClassA::getId() const { return id; }
bool operator<(const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs) {
auto r = (lhs->id < rhs->id);
::std::cout << ::std::boolalpha << "Comparing lhs->id " << lhs->id << ", with rhs->id " << rhs->id
<< ". The result is " << r << ::std::endl;
return (lhs->id < rhs->id);
}
class ClassB {
public:
::std::set<::std::shared_ptr<ClassA>> members;
void add(::std::shared_ptr<ClassA> a);
};
void ClassB::add(::std::shared_ptr<ClassA> a) {
members.emplace(::std::move(a));
}
int main() {
::std::cout << "Create first set:" << ::std::endl;
auto firstContainer = ::std::set<::std::shared_ptr<ClassA>>{::std::make_shared<ClassA>("_3"),
::std::make_shared<ClassA>("_5")};
::std::cout << "Create second set:" << ::std::endl;
auto secondContainer = ::std::set<::std::shared_ptr<ClassA>>{::std::make_shared<ClassA>("_5"),
::std::make_shared<ClassA>("_3")};
auto b1 = ::std::make_shared<ClassB>();
auto b2 = ::std::make_shared<ClassB>();
::std::cout << "Fill first ClassB instance:" << ::std::endl;
for (const auto &r: firstContainer) {
b1->add(r);
}
::std::cout << "Fill second ClassB instance:" << ::std::endl;
for (const auto &r: secondContainer) {
b2->add(r);
}
auto result = ::std::equal(b1->members.begin(), b1->members.end(), b2->members.begin(),
[](const ::std::shared_ptr<ClassA> lhs, ::std::shared_ptr<ClassA> rhs) -> bool {
return lhs->getId() == rhs->getId();
});
::std::cout << ::std::boolalpha << "The result is: " << result << ::std::endl;
::std::cout << "First ClassB members" << ::std::endl;
for (const auto &r: b1->members) {
::std::cout << "Id " << r->getId() << ::std::endl;
}
::std::cout << "Second ClassB members" << ::std::endl;
for (const auto &r: b2->members) {
::std::cout << "Id " << r->getId() << ::std::endl;
}
return 0;
}
x86-64 输出。
Create first set:
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _5, with rhs->id _3. The result is false
Create second set:
Comparing lhs->id _5, with rhs->id _3. The result is false
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _3, with rhs->id _5. The result is true
Fill first ClassB instance:
Comparing lhs->id _5, with rhs->id _3. The result is false
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _5, with rhs->id _3. The result is false
Fill second ClassB instance:
Comparing lhs->id _5, with rhs->id _3. The result is false
Comparing lhs->id _3, with rhs->id _5. The result is true
Comparing lhs->id _5, with rhs->id _3. The result is false
The result is: true
First ClassB members
Id _3
Id _5
Second ClassB members
Id _3
Id _5
aarch64输出:
Create first set:
Create second set:
Fill first ClassB instance:
Fill second ClassB instance:
The result is: false
First ClassB members
Id _3
Id _5
Second ClassB members
Id _5
Id _3
问题在这里:
bool operator<(const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs)
共享指针有它自己的 comparison operators which compares stored pointers. There is also owner_less 比较 owned 指针(一个特殊构造的共享指针可以拥有一个对象但指向另一个对象,例如它可以指向拥有对象的成员)。
如果你需要比较指向的对象,你应该写一个 comparator 这样做,并将它作为第二个模板参数传递给集合。喜欢:
struct my_ClassA_id_less {
bool operator() (const ::std::shared_ptr<ClassA> &lhs, const ::std::shared_ptr<ClassA> &rhs) {
// your comparison code here, as for operator<
}
};
::std::set<std::shared_ptr<ClassA>, my_ClassA_id_less> my_set;