以下代码导致未定义的行为:
class T
{
public:
const std::string& get() const { return s_; }
private:
std::string s_ { "test" };
}
void breaking()
{
const auto& str = T{}.get();
// do sth with "str" <-- UB
}
(因为我的理解是延长寿命const&
在这里不适用)。
为了防止这种情况,一种解决方案可能是添加一个引用限定符get()
以防止它在 LValues 上被调用:
const std::string& get() const & { return s_; }
但是,由于现在的函数既是合格的const
,&
所以仍然可以调用get()
RValues,因为它们可以分配给const&
:
const auto& t = T{}; // OK
const auto& s1 = t.get(); // OK
const auto& s2 = T{}.get(); // OK <-- BAD
防止这种情况(据我所知)的唯一方法是使用不返回引用get()
的-qualified 变体重载,或者重载它:&&
= delete
const std::string& get() const & { return s_; }
const std::string& get() const && = delete; // Var. 1
std::string get() const && { return s_; }; // Var. 2
但是,这意味着要实现正确返回 (const) 引用的 getter 函数,我总是必须提供 Var。1 oder 2.,这相当于很多样板代码。
所以我的问题是:是否有更好/更精简的方法来实现返回引用的 getter 函数,以便编译器可以识别/防止提到的 UB 案例?还是我对问题的理解存在根本缺陷?
另外,到目前为止,我还没有找到一个例子,在不处理重载的情况下添加&
到const
成员函数会带来任何好处&&
......也许任何人都可以提供一个,如果存在的话?
(我在使用 C++17 的 MSVC 2019 v142 上,如果这有什么不同的话)
感谢你并致以真诚的问候