【发布时间】:2016-07-29 02:17:30
【问题描述】:
我想使用不拥有数据但作用于其中一部分的自定义容器来遍历预分配的浮点数组。示例,命名容器类LinhaSobre:
std::unique_ptr<float[]> data(new float[720]);
...
//creates container to iterate 26 floats starting from from data[12]
LinhaSobre cont(data.get()+12, 26);
//sets those elements to 1.5
for(size_t i = 0; i < cont.size(); i++)
cont[i] = 1.5f;
这是operator[] 的可能实现:
//...
//LinhaSobre has a member mem0 which is initialized
//as a pointer to where the interval starts
float & LinhaSobre::operator[] (size_t i)
{
return *(mem0+i);
}
请注意,我将来自LinhaSobre::operator[] 的引用返回到它不拥有的数据。它不应干扰数据的生命周期(构造函数、析构函数)。
现在我想通过另一种模式std::array<float,4> 公开存储的data,而不是纯float。示例,将新类命名为LinhaSobre4f:
std::unique_ptr<float[]> data(new float[720]);
...
//creates container to iterate 4 array<float, 4> starting from from data[12]
LinhaSobre4f l(data.get()+(3*4), 4);
//sets those elements to {1.5f, 2.5f, 3.5f, 4.5f};
for(size_t i = 0; i < l.size(); i++)
l[i] = { {1.5f, 2.5f, 3.5f, 4.5f} };
请注意,我将这些项目视为一个数组。
这会导致容器类发生一些变化,我主要关心的是operator[],这是完整的类代码:
struct LinhaSobre4f
{
LinhaSobre4f(float * pos_begin, size_t size_):
pos0(pos_begin),
size_(size_){}
std::array<float, 4> & operator[](size_t i)const
{
std::array<float,4> * r =
reinterpret_cast<std::array<float,4>*> (pos0+(4*i));
return *r;
}
size_t size()const
{
return size_;
}
private:
float * pos0;
size_t size_;
};
operator[] 返回一个对被视为 std::array<float,4> 的内存块的引用,该内存块从未真正存在过,但鉴于 std::array 内存布局保证,它可以工作。我对此表示怀疑,可以吗? (除了内存对齐,我会保证)。我是否可以在语义上公开这样的对象?什么是正确的术语? (我在标题中使用了 fake object)。
Here's a live demo of the example。 Here's another (the other link sometimes fails)
【问题讨论】:
-
对我来说绝对突出的一件事(编译器会警告您)是在
LinhaSobre4f的operator[]中,您正在返回对临时变量的引用 - 您应该更改此方法的签名以按值而不是引用返回。 -
(我是吗?)本地(临时)变量是一个指针,我返回的是对它的取消引用,而不是对它的引用。
-
我认为你很安全,虽然我没有什么可以支持的。
-
"例如,将容器类命名为
LinhaSobre" =>Container会不会更分散注意力? -
@Kahler 实际上我可能错了,指针应该是安全的。
标签: c++ c++11 reference semantics dereference