Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;_C++_C++11_Reference_Semantics_Dereference - Fatal编程技术网

C++ 在C++;

C++ 在C++;,c++,c++11,reference,semantics,dereference,C++,C++11,Reference,Semantics,Dereference,我想用一个自定义容器遍历预先分配的浮点数组,该容器不拥有数据,但作用于数据的一段。例如,命名容器类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

我想用一个自定义容器遍历预先分配的浮点数组,该容器不拥有数据,但作用于数据的一段。例如,命名容器类
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;
请注意,我正在从
LinhaSobre::operator[]
返回一个对它不拥有的数据的引用。它不应该干扰数据的生命周期(构造函数、析构函数)

现在我想通过另一种模式,
std::array
公开存储的
数据,而不是单纯的
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} };
运算符[]
返回对被视为
std::array
的内存块的引用,该内存块从未真正存在过,但在
std::array
内存布局保证的情况下,它可以工作。我对此表示怀疑,可以吗?(除了内存对齐,我保证)。我可以在语义上公开这样的对象吗?正确的术语是什么?(我在标题中使用了假的对象)

< P> C++标准(我在阅读C++ 11)定义了<代码> STD::数组< /C> >如下:

应满足骨料(8.5.1)的条件

不能保证
std::array
是POD。C++标准只保证它是类集合。< /P> 基于此,我认为您使用
reinterpret\u cast
float
s的POD数组转换为
std::array
是未定义的行为


它很可能会在编译器中工作,但不能保证它是可移植的或合法的。

您可能会创建一个普通的旧引用类型:

struct LinhaSobre4f {
    struct Ref {
        Ref(float *m): m(m){};
        Ref &operator=(std::initializer_list<float> const &l) {
            std::copy(l.begin(), l.end(), m);
            return *this;
        }
    private:
        float *m;
    };
    Ref operator[](size_t i) { return m + 4 * i; }
private:
    float *m;
};
struct LinhaSobre4f{
结构参考{
Ref(float*m):m(m){};
参考和运算符=(标准::初始值设定项\u列表常量和l){
std::copy(l.begin(),l.end(),m);
归还*这个;
}
私人:
浮动*m;
};
Ref运算符[](size_t i){返回m+4*i;}
私人:
浮动*m;
};

再加上Sam Varshavchik的答案,您可能会对
span
类型()感兴趣

span
类型是一种抽象,它提供了一个对象连续序列的视图,该对象的存储由其他对象拥有(和中的更多详细信息)

从概念上讲,
span
只是指向某个存储器的指针,以及可通过该指针访问的元素计数。它太小了,可以按值传递


一个开源(仅限页眉)参考实现可在(该实现通常假设一个实现C++14支持的平台。支持MSVC 2013和2015有一些特定的解决方法)。

有一件事对我来说非常突出(编译器会就此向您发出警告)
operator[]
of
LinhaSobre4f
您正在返回对临时变量的引用-您应该将此方法的签名更改为按值返回,而不是按引用返回。(是吗?)本地(临时)变量是指针,我正在返回对它的解引用,而不是对它的引用。我认为您是安全的,虽然我没有什么可以支持的。”例如,命名容器类
LinhaSobre
“=>容器
container
会不会让人分心?@Kahler实际上我可能错了,指针应该是安全的。搜索它时,我遇到了,我可以假设它是安全的吗?如果它在当前编译器中返回true,那么它是安全的。但是,请记住,如果它在当前编译器中返回true,则不能保证它在任何其他编译器或任何未来或以前版本的编译器中返回true。我理解委托,但
运算符[]
现在返回的是值,而不是引用。。。我的愿望是能够直接在数据中操作,除此之外,
Ref
现在必须实现所有想要的操作。哇!这似乎完全符合我的设想!不过,这是一个参考类。。。不是直接访问。现在我确信C++语义不覆盖那个<代码>直接把这个内存块当作(…)< /C>。helper类必须以某种方式对访问进行编码。
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_;
};
struct LinhaSobre4f {
    struct Ref {
        Ref(float *m): m(m){};
        Ref &operator=(std::initializer_list<float> const &l) {
            std::copy(l.begin(), l.end(), m);
            return *this;
        }
    private:
        float *m;
    };
    Ref operator[](size_t i) { return m + 4 * i; }
private:
    float *m;
};