[英]'const' keyword changing semantics
I attempted today's leetcode challenge in C++.我在 C++ 中尝试了今天的 leetcode 挑战。 You have to find cousins in a binary tree.
您必须在二叉树中找到表亲。 Here's my code.
这是我的代码。
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
class Solution {
public:
bool isCousins(TreeNode* root, int x, int y) {
this->x = x;
this->y = y;
return visit(overloaded{
[](const bool& r) {
return r;
},
[](const optional<int>& r) {
return false;
}
}, helper(root));
}
private:
int x;
int y;
variant<const bool, optional<int>> helper(TreeNode* node) {
if (node == nullptr) {
return variant<const bool, optional<int>>((optional<int>()));
}
else if (node->val == x) {
return variant<const bool, optional<int>>(optional<int>(0));
}
else if (node->val == y) {
return variant<const bool, optional<int>>(optional<int>(0));
}
else {
auto l = helper(node -> left);
auto r = helper(node -> right);
return visit(overloaded{
[](const bool& l, optional<int>& r) {
assert(!r.has_value());
return variant<const bool, optional<int>>(l);
},
[](optional<int>& l, const bool& r) {
assert(!l.has_value());
return variant<const bool, optional<int>>(r);
},
[](optional<int> l, optional<int> r) {
if (l.has_value() && r.has_value()) {
return variant<const bool, optional<int>>(*l > 0 && *l == *r);
}
else if (l.has_value()) {
++*l;
return variant<const bool, optional<int>>(l);
}
else if (r.has_value()) {
++*r;
return variant<const bool, optional<int>>(r);
}
else {
return variant<const bool, optional<int>>((optional<int>()));
}
}
}, l, r);
}
}
};
A testcase that demonstrates my issue is一个证明我的问题的测试用例是
[1,3,2,null,null,7,4,null,null,5,6,null,8,null,9]
8
9
The code above runs and completes successfully.上面的代码运行并成功完成。 However, if I remove a single
const
keyword in line 10 ( [](bool& r) {
) then it returns a different (incorrect) answer.但是,如果我在第 10 行(
[](bool& r) {
)中删除了一个const
关键字,那么它会返回一个不同的(不正确的)答案。 const
is for compile-time safety, so shouldn't affect semantics, but I guess something strange is happening with const
overloading? const
是为了编译时安全,所以不应该影响语义,但我猜const
重载会发生一些奇怪的事情? What's going on exactly?究竟是怎么回事?
Possibly related: it also breaks my mental model that if, instead of declaring l
, r
in lines 34,35, I pass them directly as arguments to visit (ie. return visit(overloaded{..}, helper(node->left), helper(node->right)
), it also fails. I would again expect that to have no effect on semantics. Possibly related: it also breaks my mental model that if, instead of declaring
l
, r
in lines 34,35, I pass them directly as arguments to visit (ie. return visit(overloaded{..}, helper(node->left), helper(node->right)
), 它也失败了。我再次希望这对语义没有影响。
Removing the const
in this case changes the meaning of the code, by changing which function is selected in overload resolution.在这种情况下删除
const
会更改代码的含义,通过更改在重载决议中选择的 function。
Consider the following overload set and call:考虑以下重载集和调用:
void f(int const &) { std::cout << "i"; }
void f(bool) { std::cout << "b"; }
int main()
{
int const i = 42;
f(i); // prints i
f(42); // prints i
}
both call the first function (as expected), because a int const &
binds to a int const
, as well as int&&
(a temporary int
).两者都调用第一个 function (如预期的那样),因为
int const &
绑定到int const
以及int&&
(临时int
)。
However, if we remove the const
in the first function of the overload set, and make the same call:但是,如果我们删除重载集的第一个 function 中的
const
,并进行相同的调用:
void f(int &) { std::cout << "i"; }
void f(bool) { std::cout << "b"; }
int main()
{
int const i = 42;
f(i); // prints b
f(42); // prints b
}
the first function is not selected, because an int &
, cannot bind to a int const
.第一个 function 没有被选中,因为
int &
不能绑定到int const
。 However, a bool
can bind to an int const
, (after an implicit conversion), and it calls the second function.但是,
bool
可以绑定到int const
(在隐式转换之后),并且它调用第二个 function。 Similarly, an int &
cannot bind to a int&&
, but a bool
can, so it calls the second function.同样,
int &
不能绑定到int&&
,但bool
可以,因此它调用第二个 function。
This same reasoning applies to your example, but I've removed the variant
, and custom overload set, as it simplifies the situation, without changing the underlying problem.同样的推理也适用于您的示例,但是我删除了
variant
和自定义重载集,因为它简化了情况,而没有改变潜在的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.