在set find中传递一对long long是否安全?

huangapple go评论60阅读模式
英文:

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&lt;std::pair&lt;int, int&gt;&gt; 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 宽度的唯一值。

如果 xy 的值超出了 int 的范围,这意味着 z 可能会变为 false,尽管在集合中可能没有一对值的 xy 与集合中的一对值在数学上相等。

然而,除此之外,一切都没有问题。从 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&lt;int, int&gt;.

This comes with all drawbacks of you creating a std::pair&lt;int, int&gt; from values that may exceed the range of int.

std::set&lt;std::pair&lt;int, int&gt;&gt; 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 &lt;&lt; std::boolalpha &lt;&lt; z &lt;&lt; &#39;\n&#39;; // prints false

huangapple
  • 本文由 发表于 2023年5月28日 19:20:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76351224.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定