在原位进行危险的隐式转换
Dangerous implicit conversion in emplace
以下代码在 gcc 6.3 (https://godbolt.org/g/sVZ8OH) 中编译时没有任何错误/警告,但由于下面标记的内存访问无效,它包含危险的未定义行为。根本原因是在emplace_back中执行的隐式转换。任何人都可以建议一种好方法或最佳实践来避免代码中的此类错误吗?
#include <iostream>
#include <vector>
struct Foo
{
explicit Foo(const int& i) : i{i} {}
void foo() const { std::cout << i; } // invalid memory access, as i is an invalid ref!!
const int& i;
};
void bar(const double& d) {
std::vector<Foo> fv;
fv.emplace_back(d);
}
如果要接受 const 引用,但不希望引用临时引用,请使用 rvalue 引用参数声明一个额外的构造函数 - 并将其删除。
struct Foo
{
explicit Foo(const int& i) : i{i} {}
explicit Foo(const int&& i) = delete; // This preferentially matches a reference to a
// temporary, and compilation fails.
void foo() const { std::cout << i; } // invalid memory access, as i is an invalid ref!!
const int& i;
};
(我假设实际问题比整数更复杂。 对于 int,按值持有它是正确的答案。
任何人都可以建议一种好方法或最佳实践来避免代码中的此类错误吗?
当你的类存储对另一个对象的const
引用时,作为程序员,你有责任确保你最终不会存储一个悬而未决的引用。
除非您有充分的理由存储const
引用,否则我建议您存储一个值。
struct Foo
{
explicit Foo(const int& i) : i{i} {}
void foo() const { std::cout << i; }
int i;
};
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 从 int 到 longlong 的危险转换:没有警告
- C++ 隐式转换:良好的特异性或对程序行为的危险
- 在原位进行危险的隐式转换
- 从双精度到布尔值的 C++ 隐式转换是危险的
- 是否危险将 int * 转换为无符号的 int *
- 在UTF-8内部工作,然后仅在Windows中需要时转换为UTF-16,是否存在任何危险
- 这有多危险?(列表<T>正在强制转换为列表<常量 T>)
- 以任何方式将基指针强制转换为派生指针是否危险
- 指针强制转换以满足方法参数是一件危险的事情吗?