Я попытался сегодняшнее испытание leetcode на C ++. Вы должны найти кузенов в двоичном дереве. Вот мой код.
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
Приведенный выше код выполняется и успешно завершается. Однако, если я удалю одно ключевое слово const
в строке 10 ([](bool& r) {
), оно вернет другой (неправильный) ответ. const
предназначен для безопасности во время компиляции, поэтому не должен влиять на семантику, но я думаю, что-то странное происходит с перегрузкой const
? Что именно происходит?
Возможно, связано: это также нарушает мою ментальную модель, согласно которой, если вместо объявления l
, r
в строках 34,35 я передаю их напрямую в качестве аргументов для посещения (ie. return visit(overloaded{..}, helper(node->left), helper(node->right)
), тоже не получается. Я бы снова ожидал, что это не повлияет на семантику.