C ++禁止访问临时文件

问题描述 投票:2回答:2

我正在研究一个类似于std::variant的类,因为它使用联合以及错误代码来存储另一个对象。像std::variant一样,有一个get_if()函数可用于访问类中的对象。所以像这样]

template<typename T>
class result final 
{
    ...
    [[nodiscard]] constexpr T const *
    get_if() const noexcept
    {
        if (details::result_type::contains_t == m_which) {
            return &m_t;
        }

        return nullptr;
    }
    ...
};

现在...假设您有一个使用此类的对象返回对象的函数,如下所示:

[[nodiscard]] static bsl::result<example_implementation>
make(bsl::int32 const answer) noexcept
{
    constexpr bsl::int32 valid_answer{42};

    if (answer == valid_answer) {
        return {bsl::in_place, valid_answer};
    }

    return {bsl::errc_failure, bsl::here()};
}

所有这些都很棒。我关注的问题是用户是否执行以下操作:

if (auto const impl = example_implementation::make(valid_answer).get_if()) {
    example_bind_apis_type enforced_impl{*impl};

    if (enforced_impl.member_func_example(valid_answer)) {
        bsl::print("success\n");
    }

    if (!enforced_impl.member_func_example(invalid_answer)) {
        bsl::print("success\n");
    }
}
else {
    bsl::print("failure\n");
}

[在上面的示例中,用户正在创建example_implementation,然后使用get_if()获取指向由结果对象包装的对象的指针。然后将该指针取消引用并使用。 ASAN会在销毁对象后检测到已使用堆栈,这是由于“ if”语句创建了一个临时结果对象,然后返回了指向该临时内部对象的指针,该指针在调用[后被删除C0]。这类似于我记得几年前的get_if()问题,当时人们会从一个临时对象获取QString内部的C样式字符串的指针。

在C ++中,有没有一种方法可以防止用户像这样的临时用户调用QString?我尝试了引用限定符get_if(),但由于上面的make函数返回的是左值而不是右值,所以这似乎不起作用(即使RVO可能会删除副本)。我要做的就是防止用户意外地犯此错误。

更新:

如评论中所述,make()返回的是右值,而不是如上所述的左值,因此ref限定符应该起作用。

我正在研究一个类似于std :: variant的类,因为它使用联合以及错误代码存储了另一个对象。像std :: variant一样,有一个get_if()函数可用于...

c++
2个回答
4
投票

您可能在方法中使用引用限定符:


0
投票

@@ Eljay在上面的评论中指出了这一点。您需要显式删除函数的右值引用限定版本。

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