Присвойте Index внутри класса, используя std :: vector - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть std :: vector из 30 экземпляров, инициализированных так:

#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 голосов
/ 18 сентября 2018

Значение, которое вы передаете во втором параметре конструктора 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


Обновление : благодаря Франсуа Андрие в комментариях у меня была еще одна идея, связанная с 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

0 голосов
/ 18 сентября 2018

Вы хотите, чтобы переменная-член Foo была индексом в векторе? Просто вызовите ctor для каждого члена и вставьте его в вектор.

#include <vector>

class Foo {
public:

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

    Foo(int _index, int& _x) : Index(_index), a(_x) {} 

    void func(){
        // Do something cool ...
    }

};

int main(){

    int a = 5;
    std::vector<Foo> Instances;
    Instances.reserve(30);
    for(size_t i=0;i<30;i++)
       Instances.emplace_back(i,a);
    return 0;

}
...