c ++向量从构造函数分配对象而不是临时的

Posted

技术标签:

【中文标题】c ++向量从构造函数分配对象而不是临时的【英文标题】:c++ vector assign object from constructor without temporary 【发布时间】:2015-03-30 09:04:03 【问题描述】:

我有一个类体素,它是用模板制作的,参数 dim 是空间维度(2D/3D):

template<int dim>
class Voxel
typedef Eigen::Matrix<float, dim, 1> vect;
private:
    vect Position; 
    vect Frequence; 

public:
    Voxel(vector<float>&, vector<float>& );
;

template<int dim>
Voxel<dim>::Voxel(vector<float> &coordinates, vector<float> &frequence)
    assert( ((dim==2) || (dim==3)) && "Spatial dimension at voxel   creation must be 2 or 3");
    for (int i; i<dim; ++i)
        Position[i] = coordinates[i]; 
        Frequence[i] = frequence[i];
     

在另一个对象中:我有

template<int dim>
class Grid
private:
    vector<float> size;
    vector<Voxel<dim>> voxels; ///< @brief List of the points. Maybe should be pointers ?
    unsigned int nb_voxels; ///< @brief total number of voxels in the grid
public:
    Grid(vector<float>&, vector<int>& );
;

template<int dim>
Grid<dim>::Grid(vector<float> &size, vector<int> &resolution)
    : size(size)

    nb_voxels = resolution[0];
    for (int d = 1; d < dim; ++d) 
        nb_voxels *= resolution[d];
    
    voxels.resize(nb_voxels);
    vector<float> pos;
    pos.resize(dim);
    vector<float> freq;
    freq.resize(dim);

    vector<float> possible_coordinates;
    possible_coordinates.resize(nb_voxels);
    for (int d = 0; d < dim; ++d) 
        for (int k = 0; k < resolution[d] ; ++k) 
            possible_coordinates[k + d*resolution[d]] = k * size[d]/(resolution[d]-1); //ok
        
    

    for (int elem = 0; elem < nb_voxels; ++elem) 
        for (int d = 0; d < dim; ++d) 
            pos[d] = 0; //fixme
        
        Voxel<dim> v(pos, freq);
        voxels[elem]= v;
    
    cout << "nb points="<< nb_voxels <<endl;

最后是主要的:

int main ()

    vector<float> dimensions = 4, 8;
    vector<int> resolution = 2, 4; ///< @brief must be >1 on each dim

        space_dim = dimensions.size();

    for (int d = 0; d < space_dim; ++d) 
        assert( (resolution[d]%2 == 0) && "resolution must be even");
    

    if (space_dim == 2) 
        Grid<2> Grid(dimensions, resolution);
    
    else if (space_dim == 3)
        Grid<3> Grid(dimensions, resolution);
    
    return 0;

为什么我不能这样做?

voxels[elem] = Voxel<dim>(pos, freq);

也不是这个:

Voxel<dim> v (pos, freq);
voxels[elem] = v;

但我可以:没有调整矢量大小并做:

    Voxel<dim> v(pos, freq);
    voxels.push_back(v);

我认为 Voxel(pos, freq) 会返回对象的一个​​实例并将其复制到元素中?

谢谢

【问题讨论】:

Voxel 类模板中可能有问题(例如复制构造函数或赋值运算符采用非常量引用)。最好发一个MCVE。 好的,我看到你完全改变了问题。不过,您还没有 MCVE。 对不起,我忘记了 main 和构造函数。我想现在一切都在那里。 【参考方案1】:

您正在调用std::vector::resize,它将调用值类型的默认构造函数,但Voxel 中没有构造函数,因此会出现编译时错误。

使用std::vector::reserve 分配内存而不尝试默认构造。

【讨论】:

谢谢,这似乎在编译时和运行时都有效。 (我可以在 gdb voxels[3].position[0] 中打印,我似乎得到了正确的结果。我不明白为什么在 link 中调整大小不起作用。你能提供更多参考吗? 来自该链接“如果 n 大于当前容器大小,则通过在末尾插入所需数量的元素来扩展内容以达到 n 的大小。如果指定了 val,则新的元素被初始化为 val 的副本,否则,它们被值初始化”。这意味着分配了内存并且使用默认构造函数初始化对象。 Voxel 没有默认构造函数。 好的,我想我明白了。谢谢你。这意味着我必须有一个构造函数 Voxel(),它似乎可以工作。非常感谢 如果你想使用resize,可以。【参考方案2】:

体素[elem]

返回对elem 位置元素的引用(无效),因为向量为空。您需要首先使用std::vector::resize 将元素推送到向量,这将通过调用默认构造函数将元素推送到向量,以便使用operator[]。这应该有效:

vector<Voxel<dim>> voxels(nb_voxels);  //push nb_voxels to voxels vector

vector<Voxel<dim>> voxels;
voxels.resize(nb_voxels);

然后

voxels[elem] = Voxel<dim>(pos, freq);

【讨论】:

谢谢。我确实有矢量>体素;在类定义中,我做 voxels.resize(nb_voxels);在 Grid::Grid(...) 然而,voxels[elem] = Voxel(pos, freq) 返回编译器错误 error: no matching function for call to 'Voxel::Voxel( )'

以上是关于c ++向量从构造函数分配对象而不是临时的的主要内容,如果未能解决你的问题,请参考以下文章

如何声明其类没有默认构造函数的对象数组?

对复制构造函数已被删除的对象向量进行迭代 (C2280)

C++ - 未分配被释放的指针

vector 如何在特定位置调用复制构造函数?

具有私有构造函数和析构函数的类对象的向量?

何时删除复制构造函数