这是一个如此简单的模式,必须有一个很好的"整理出来的方式。
我有一个函数需要生成一个包含算术数据的动态大小的字节数组。
// Given that I have a function that kinda looks like this:
void dispatch(std::vector<char> data); //Will take possesion of data.
// The behavior I want, but this breaks strict aliasing
void bad_foo(int c) {
std::vector<char> real_data(c * sizeof(float));
float* raw_data = reinterpret_cast<float*>(real_data.data());
//Fill raw_data with usefull stuff...
dispatch(std::move(real_data));
}
void correct_but_slow_foo(int c) {
std::vector<float> raw_data(c);
//Fill raw_data with usefull stuff...
std::vector<char> real_data(c * sizeof(float));
std::memcpy(real_data.data(), raw_data.data(), c * sizeof(float));
dispatch(std::move(real_data));
}
不幸的是,似乎即使是clang的堆缺乏也无法解决这里需要做的事情:see on godbolt
在最糟糕的情况下,我可以将dispatch()
作为模板,但这会变得非常混乱,我很想知道是否有办法摆脱这种混乱我忽略了反正。
谢谢!
编辑:我想到了一个想法(当然是在发布问题后立即......):我可以将real_data
视为一个分配池而就地新算术最重要的数据:
void fixed_foo(int c) {
std::vector<char> real_data(c * sizeof(float));
float* raw_data = new (real_data.data()) float[c];
//Fill raw_data with usefull stuff...
dispatch(std::move(real_data));
}
这看起来很时髦,但我认为&#34;这可能是合法的。可能?
答案 0 :(得分:2)
解决别名规则的最安全方法是使用memcpy()
,但您不需要在整个第二个数据副本上执行此操作。我建议您对本地float
变量进行所有float
工作,然后memcpy()
将real_data
缓冲区放在void better_foo(int c) {
std::vector<char> real_data(c * sizeof(float));
//Fill raw_data with usefull stuff...
for (int i = 0; i < c; ++i) {
float x = my_complicated_calculation(i);
memcpy(&real_data[i * sizeof(float)], &x, sizeof(x));
}
dispatch(std::move(real_data));
}
缓冲区中的适当位置。大多数编译器都会根据我的经验有效地优化它。
@Entity
@Table(name="OBJECTSTERMIC")
public class TermicObject {
@Id
@Column(name="TERMICID")
private long termicId;
@MapsId
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="OBJECTID",columnDefinition="INTEGER")
private Object object;
@Column(name="CONTECA_RIF")
private int contecaRif;
@Column(name="CONTECA_VAL")
private int contecaVal;
@Column(name="TYPE")
private String type;
//getters and setters