[英]'const' keyword changing semantics
我在 C++ 中尝试了今天的 leetcode 挑战。 您必须在二叉树中找到表亲。 这是我的代码。
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);
}
}
};
一个证明我的问题的测试用例是
[1,3,2,null,null,7,4,null,null,5,6,null,8,null,9]
8
9
上面的代码运行并成功完成。 但是,如果我在第 10 行( [](bool& r) {
)中删除了一个const
关键字,那么它会返回一个不同的(不正确的)答案。 const
是为了编译时安全,所以不应该影响语义,但我猜const
重载会发生一些奇怪的事情? 究竟是怎么回事?
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)
), 它也失败了。我再次希望这对语义没有影响。
在这种情况下删除const
会更改代码的含义,通过更改在重载决议中选择的 function。
考虑以下重载集和调用:
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
}
两者都调用第一个 function (如预期的那样),因为int const &
绑定到int const
以及int&&
(临时int
)。
但是,如果我们删除重载集的第一个 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
}
第一个 function 没有被选中,因为int &
不能绑定到int const
。 但是, bool
可以绑定到int const
(在隐式转换之后),并且它调用第二个 function。 同样, int &
不能绑定到int&&
,但bool
可以,因此它调用第二个 function。
同样的推理也适用于您的示例,但是我删除了variant
和自定义重载集,因为它简化了情况,而没有改变潜在的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.