我在C ++中尝试了today's leetcode challenge。您必须在二叉树中找到表亲。这是我的代码。
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行(const
)中删除了一个[](bool& r) {
关键字,则它将返回另一个(错误的)答案。 const
用于编译时安全,因此不应该影响语义,但是我想const
重载正在发生奇怪的事情?到底是怎么回事?
[可能相关:这也破坏了我的思维模式,如果我没有在第34,35行中声明l
,r
,而是直接将它们作为要访问的参数(即return visit(overloaded{..}, helper(node->left), helper(node->right)
)传递,那么它也会失败。我再次希望它对语义没有影响。
在这种情况下,删除const
会通过更改在过载分辨率中选择的功能来更改代码的含义。考虑以下重载设置并调用:
void f(int const &) { std::cout << "i"; }
void f(bool) { std::cout << "b"; }
int main()
{
int const i = 42;
f(i); // prints i
}
它调用第一个函数(如预期的那样,因为int const &
绑定到int const
。
但是,如果我们删除过载集合的第一个函数中的const
,并进行相同的调用:
void f(int &) { std::cout << "i"; }
void f(bool) { std::cout << "b"; }
int main()
{
int const i = 42;
f(i); // prints b
}
未选择第一个功能,因为int &
无法绑定到int const
。但是,bool
可以绑定到int const
(在隐式转换之后),并调用第二个函数。