以下短节目
#include <vector>
#include <iostream>
std::vector<int> someNums()
{
return {3, 5, 7, 11};
}
class Woop
{
public:
Woop(const std::vector<int>& nums) : numbers(nums) {}
void report()
{
for (int i : numbers)
std::cout << i << ' ';
std::cout << '\n';
}
private:
const std::vector<int>& numbers;
};
int main()
{
Woop woop(someNums());
woop.report();
}
Run Code Online (Sandbox Code Playgroud)
有一个悬空引用问题,似乎没有编译器警告过。问题是临时文件可以绑定到 const-refs,然后您可以保留它。那么问题是;有没有办法避免陷入这个问题?最好是不涉及牺牲常量正确性或总是制作大对象的副本。
Gem*_*lor 11
使您的类不那么容易受到攻击的一种方法是添加一个带有右引用的已删除构造函数。这将阻止您的类实例绑定到临时对象。
Woop(std::vector<int>&& nums) =delete;
Run Code Online (Sandbox Code Playgroud)
这个删除的构造函数实际上会使 O/P 代码无法编译,这可能是您正在寻找的行为?
在某些方法在返回后保留引用的情况下,使用std::reference_wrapper而不是正常引用是个好主意:
#include <functional>
class Woop
{
public:
using NumsRef = ::std::reference_wrapper<const std::vector<int>>;
Woop(NumsRef nums) : numbers_ref{nums} {}
void report()
{
for (int i : numbers_ref.get())
std::cout << i << ' ';
std::cout << '\n';
}
private:
NumsRef numbers_ref;
};
Run Code Online (Sandbox Code Playgroud)
Woop (std::vector<int> const &&) = delete;为您的方法使用右值而担心额外的禁止重载:Woop woop{someNums()}; // error
woop.report();
Run Code Online (Sandbox Code Playgroud)
auto nums{someNums()};
Woop woop{nums}; // ok
woop.report();
Run Code Online (Sandbox Code Playgroud)
auto nums{someNums()};
Woop woop{::std::ref(nums)}; // even better because explicit
woop.report();
Run Code Online (Sandbox Code Playgroud)