到位危险的隐式转换 [英] Dangerous implicit conversion in emplace
问题描述
以下代码使用gcc 6.3( https://godbolt.org/g/sVZ8OH 进行编译,不会出现任何错误/警告。 ,但是由于下面标记了无效的内存访问,它包含危险的不确定行为。根本原因是在emplace_back中执行的隐式转换。有人可以建议一种避免此类代码错误的好方法或最佳实践吗?
The following code compiles without any errors/warnings with gcc 6.3 (https://godbolt.org/g/sVZ8OH), but it contains a dangerous undefined behavior due to invalid memory access marked below. The root cause is the implicit conversion performed in emplace_back. Can anyone suggest a good way or best practices to avoid such bugs in code?
#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引用参数声明一个附加构造函数-并将其删除。
If you are going to accept a const reference, but you don't want a reference to a temporary, declare an additional constructor with an rvalue reference argument - and delete it.
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复杂。对于int,持有按值算是正确的答案。)
(I am assuming that the actual problem is more complex than just an int. For an int, holding it by value is the right answer.)
这篇关于到位危险的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!