【发布时间】:2021-08-09 05:53:12
【问题描述】:
我认为 VS2019 的建议会产生悬空参考情况,但我对其进行了测试,它似乎有效。这里发生了什么?
template<typename MessageType>
class Queue {
inline static std::vector<MessageType> messages;
public:
static bool isEmpty() {
return messages.size() == 0;
}
template <typename... Args>
static void emplace(Args&&... args) {
messages.emplace_back(std::forward<Args>(args)...);
}
static MessageType pop() {
auto const& val = messages.back();
messages.pop_back();
return val;
}
};
看起来最后一条消息的存活时间足够长,可以复制到返回值中。这是好的做法吗?
【问题讨论】:
-
编译器没有义务找出编译代码中未定义行为的每个实例。每次它设法提醒您未定义的行为时,请将其视为额外的奖励。编译器在这里错过了这一点的事实仅仅意味着您不能总是期望您的编译器为您捕获所有错误。如果有就好了,但我们不能总是有好的东西......
-
VS 在这里是错误的:通过这些更改,这绝对是未定义的行为。
-
您可以更改代码以避免与 warning 相关的 C++ 核心指南,方法是不使用
auto作为类型:messageType val = messages.back();。 -
auto const& val = messages.back(); messages.pop_back(); return val;是未定义行为,因为val指的是在到达return时已销毁的对象。但是auto const val = messages.back(); messages.pop_back(); return val;完全没问题,因为val是向量最后一个元素的副本,所以原件是否被破坏并不重要。 -
@alfC:在屏幕截图中,
val不是参考。在后面的代码中就是。
标签: c++ reference visual-studio-2019 dangling-pointer