Инициализировать вектор ‹vector ‹mytype›› член в конструкторе

У меня есть класс, член которого является вектором векторов:

class binary_image_field_2d {
public:
    typedef double field_value_t;
    typedef vector<field_value_t> field_t;
protected:
    size_t _ndots;
    size_t _nfields;
    vector<field_t> _fields;
}

Я хочу иметь конструктор, который может инициализировать на месте каждый из (внутренних) векторов с другим постоянным значением:

binary_image_field_2d(const size_t ndots, const size_t nfields, const vector<field_value_t> init_vals) : 
    _ndots(ndots), _nfields(nfields), 
    _fields( initialize here each element of _fields with a vector of
             constant value given by an element of init_vals ) {};

Например, если ndots=3, nfields=2 и init_vals={0.1, 1.0}, с

binary_image_field_2d img;

Я хочу получить

{{0.1, 0.1, 0.1}, {1.0, 1.0, 1.0}}

Как это должно быть написано (если вообще возможно)?


person sancho.s ReinstateMonicaCellio    schedule 16.05.2019    source источник
comment
Создайте частную функцию-член, которая делает это, и вызовите эту функцию из конструктора.   -  person Michael Chourdakis    schedule 16.05.2019


Ответы (1)


Вы можете сделать это с помощью частной функции в конструкторе:

#include <vector>
#include <iostream>
#include <cstdint>

class binary_image_field_2d
{
public:
    typedef double field_value_t;
    typedef std::vector<field_value_t> field_t;
    binary_image_field_2d(const size_t ndots, const size_t nfields, const std::vector<field_value_t> init_vals) : _ndots(ndots), _nfields(nfields),_fields(init_fields(ndots, nfields, init_vals))
    {// Empty constructor}

protected:
    size_t _ndots;
    size_t _nfields;
    std::vector<field_t> _fields;

private:
    std::vector<field_t> init_fields(const size_t ndots, const size_t nfields, const std::vector<field_value_t> init_vals)
    {
        std::vector<field_t> vec;
        for (int i = 0; i < nfields; ++i)
        {
            vec.emplace_back(std::vector(ndots, init_vals[i]));
        }
        return vec;
    }
public:
    void print_fields()
    {
        for (auto vec : _fields)
        {
            for (auto value : vec)
            {
                std::cout << value << " ";
            }
            std::cout << std::endl;
        }
    }
};

int main(void)
{
    binary_image_field_2d b(3, 2, {0.1f, 1.1f});
}

Вы также можете сделать это с помощью лямбда-функции вместо частной функции:

#include <vector>
#include <iostream>
#include <cstdint>

class binary_image_field_2d
{
public:
    typedef double field_value_t;
    typedef std::vector<field_value_t> field_t;
    binary_image_field_2d(const size_t ndots, const size_t nfields, const std::vector<field_value_t> init_vals) : _ndots(ndots), _nfields(nfields), 
    _fields([init_vals, nfields, ndots]() -> std::vector<field_t> {                                                                                                                      
        std::vector<field_t> vec;                                                                                                                      
        for (int i = 0; i < nfields; ++i)                                                                                                                      
        {                                                                                                                          
            vec.emplace_back(std::vector(ndots, init_vals[i]));                                                                                                                      
        }                                                                                                                          
        return vec;                                                                                                                  
    }())
    {// Empty constructor}

    void print_fields()
    {
        for (auto vec : _fields)
        {
            for (auto value : vec)
            {
                std::cout << value << " ";
            }
            std::cout << std::endl;
        }
    }    
protected:
    size_t _ndots;
    size_t _nfields;
    std::vector<field_t> _fields;
};

int main(void)
{
    binary_image_field_2d b(3, 2, {0.1f, 1.1f});
    b.print_fields();
}

в обоих случаях program_output будет:

0.1 0.1 0.1 
1.1 1.1 1.1   
person Clonk    schedule 16.05.2019
comment
Еще не пробовал, но оба варианта неплохо смотрятся! - person sancho.s ReinstateMonicaCellio; 16.05.2019