使用std :: vector在类内分配索引

时间:2018-09-18 00:23:12

标签: c++ class vector operator-overloading stdvector

我有一个30个实例的std :: vector像这样初始化:

#include <vector>

class Foo {
public:

    int x;
    int Index;  // I want this to be initialized when std::vector start the 
                // Instances.

    Foo(int& _x) : x(_x) {} 

    int Function(){
        // Do something cool ...
    }

};

int main(){

    int a = 5;
    std::vector<Foo> Instances (30, a);
    return 0;

}

所以我希望当我调用std::vector<Foo> Instances (30, SomeVariablePassedByReference);时,每个实例的每个成员变量Index得到对应的数字(0-30)。

我该怎么做?也许使用运算符重载?我不想使用C-Stylish []运算符

2 个答案:

答案 0 :(得分:3)

您想让Foo的成员变量成为向量内的索引吗?只需为每个成员调用ctor并将其推入引导程序即可。

ctrlplot<-ctrl %>% ggplot(aes(x=x, y=y)) +
  stat_density_2d(geom = "raster", aes(fill = stat(density)), contour = FALSE)+
  scale_fill_gradientn(colours=matlab.like(15), na.value = "gray")


ctxplot<-ctx %>% ggplot(aes(x=x, y=y)) +
  stat_density_2d(geom = "raster", aes(fill = stat(density)), contour = FALSE)+
  scale_fill_gradientn(colours=matlab.like(15), na.value = "gray")


ctrlplot2<-ggplot_build(ctrlplot)
gbctrl<-ctrlplot2$data[[1]]
 densctrl<-gbctrl$density

gbctx<-ggplot_build(ctxplot)
gbctx<-gbctx$data[[1]]
 densctx<-gbctx$density

diff_ctrl_ctx<-densctrl-densctx

gbctrl$density<-diff_ctrl_ctx
ctrlplot2$data[[1]]<-gbctrl

ctrlplot2
ctrlplot

答案 1 :(得分:3)

您在vector的构造函数的第二个参数中传递的值会按原样传递给创建的每个元素的副本构造函数。由于您要创建vector个对象的Foo,因此第二个参数本身就是一个Foo对象,因此您要创建一个Foo的临时int作为输入,然后将该临时变量传递给Foo中每个vector实例的副本构造函数。

因此,您所寻找的语法最接近的内容如下:

class Foo
{
public:
    ...
    int a;
    int Index;

    Foo(int _x) : a(_x), Index(-1) {} 
    Foo(const Foo &_f) : a(_f.a) { Index = ++(const_cast<Foo&>(_f).Index); } 
    ...
};

int main()
{
    int a = 5;

    // this (implicitly) creates a temp Foo object using the 'Foo(int)'
    // constructor, and then copy-constructs the Foo objects in the
    // vector passing that temp to the 'Foo(const Foo&)' constructor...
    std::vector<Foo> Instances (30, a);

    return 0;
}

Live Demo

但是,这是对C ++语言的公然不安全滥用,因此请不要使用它。

更安全的选择是在填充vector之后简单地初始化索引,例如:

class Foo
{
public:
    ...
    int a;
    int Index;

    Foo(int _x) : a(_x), Index(-1) {} 
    ...
};

int main()
{
    int a = 5;
    std::vector<Foo> Instances (30, a);

    // yes, I know, you don't want to use the operator[], but it
    // is a safer option...
    for(size_t index = 0; index < Instances.size(); ++index)
        Instances[index].Index = index;

    // unless you use iterators instead...
    /*
    size_t index = 0;
    for (std::vector<Foo>::iterator iter = Instances.begin(); iter != Instances.end(); ++iter)
        iter->Index = index++;
    */
    /*
    size_t index = 0;
    for (auto &f : Instances)
        f.Index = index++;
    */

    return 0;
}

Live Demo


更新:多亏了François Andrieux的评论,我想到了另一个涉及std::generate_n()的想法,可以根据需要为您创建索引。尽管它不是您要查找的语法:

#include <vector>
#include <algorithm>
#include <utility>

struct MyIndexGenerator
{
    int value;
    int index;

    MyIndexGenerator(int _value, int _first = 0) : value(_value), index(_first) {}

    std::pair<int, int> operator()()
    { 
        return std::make_pair(value, index++);
    }
};

class Foo
{
public:
    int x;
    int Index;

    Foo(const std::pair<int, int> &_x) : x(_x.first), Index(_x.second) {} 

    ...
};

int main()
{
    int a = 5;
    std::vector<Foo> Instances;
    Instances.reserve(30);
    std::generate_n(std::back_inserter(Instances), 30, MyIndexGenerator(a));
    return 0;
}

Live Demo