''const'关键字更改语义

问题描述 投票:-1回答:1

我在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行中声明lr,而是直接将它们作为要访问的参数(即return visit(overloaded{..}, helper(node->left), helper(node->right))传递,那么它也会失败。我再次希望它对语义没有影响。

c++ const
1个回答
0
投票

在这种情况下,删除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(在隐式转换之后),并调用第二个函数。

© www.soinside.com 2019 - 2024. All rights reserved.