英文:
Is passing a pair of long long in set find safe?
问题
我有以下的代码:
std::set<std::pair<int, int>> my_set;
long long x = (某个值);
long long y = (某个值);
// 如果x或y超出int的限制,则应返回true
bool z = my_set.find({x, y}) == my_set.end();
它没有任何错误并且似乎工作正常。但是,我想知道是否'安全',因为我正在向find
函数传递一个long long
的pair。
英文:
I have the following code:
std::set<std::pair<int, int>> my_set;
long long x = (some value);
long long y = (some value);
// should be true if x or y exceed the limits of int
bool z = my_set.find({x, y}) == my_set.end();
It works without any errors and seems to work correctly. But, I wonder if it's 'safe' because I am passing a pair of long long
to the find
function.
Thanks!
答案1
得分: 1
不安全的地方在于实际比较的值可能与您期望的不同。
这两个 long long
值将被转换为 int
,然后 find
函数将查找一个包含这两个转换后的 int
值的 pair
。自从C++20以来,保证此转换会产生等于原始值对2的整数幂取模后的 int
宽度的唯一值。
如果 x
和 y
的值超出了 int
的范围,这意味着 z
可能会变为 false
,尽管在集合中可能没有一对值的 x
和 y
与集合中的一对值在数学上相等。
然而,除此之外,一切都没有问题。从 long long
转换为 int
后的搜索将按预期工作。
英文:
It is not safe in as far as the values that will actually be compared may not be what you expect.
The two long long
values will be converted to int
and then find
will look for a pair
containing these two converted int
values. Since C++20 it is guaranteed that this conversion produces the unique value represented by int
that is equal to the original value modulo 2 to the power of the width of int
.
If the values of x
and y
will fall outside the range of int
, this means that z
may become false
even though there may not be a pair in the set for which the values of x
and y
are (mathematically) equal to those of the pair in the set.
However, aside from that, there is nothing wrong. The search after conversion from long long
to int
will work exactly as expected.
答案2
得分: 1
你没有将一对 long long
传递给函数。由于您没有指定传递给 std::set::find
的键的类型,编译器使用了一个接受对 const 键对象的左值引用的构造函数,即在这种情况下是 std::pair<int, int>
。
这带来了一个问题,即您从可能超出 int
范围的值创建了一个 std::pair<int, int>
。
std::set<std::pair<int, int>> my_set;
my_set.emplace(0, 0);
long long x = 0x100000000;
long long y = 0;
// 如果 x 或 y 超出 int 的限制,则应该为 false
bool z = my_set.find({ x, y }) == my_set.end();
std::cout << std::boolalpha << z << '\n'; // 输出 false
英文:
You are not passing a pair of long long
to the function. Since you did not specify the type of the key passed to std::set::find
, the compiler uses the constructor taking a lvalue reference to a const Key object, i.e. in this case std::pair<int, int>
.
This comes with all drawbacks of you creating a std::pair<int, int>
from values that may exceed the range of int
.
std::set<std::pair<int, int>> my_set;
my_set.emplace(0, 0);
long long x = 0x100000000;
long long y = 0;
// should be false if x or y exceed the limits of int
bool z = my_set.find({ x, y }) == my_set.end();
std::cout << std::boolalpha << z << '\n'; // prints false
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论