gpt4 book ai didi

C++ 阻止访问临时对象

转载 作者:行者123 更新时间:2023-12-01 19:53:48 25 4
gpt4 key购买 nike

我正在开发一个类似于 std::variant 的类,它使用 union 和错误代码存储另一个对象。与 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”语句创建了一个临时结果对象,然后返回了一个指向该临时对象内部内容的指针,该指针在调用 get_if() 后被删除。这与我记得几年前的 QString 问题类似,当时人们会从临时变量中获得指向 QString 内的 C 样式字符串的指针。

在 C++ 中是否有办法阻止用户在这样的临时对象上调用 get_if()?我尝试引用限定 get_if() ,但这似乎不起作用,因为上面的 make 函数返回左值,而不是右值(即使 RVO 可能会删除拷贝)。我想做的就是防止用户意外地犯这个错误。

更新:正如评论中所述, make() 返回一个右值,而不是我上面所说的左值,因此 ref 限定符应该起作用。

最佳答案

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

template<typename T>
class result final
{
// ...
[[nodiscard]] constexpr T const* get_if() const & noexcept;

constexpr void get_if() && noexcept = delete;

// ...
};

Demo

关于C++ 阻止访问临时对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60320022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com