Как инициализировать список константного члена std :: array, используя аргумент конструктора std :: array C ++ - PullRequest
0 голосов
/ 27 ноября 2018

предположим, что у нас есть следующий класс в C ++ 11 или новее:

class MyClass {
private:
    const std::array<SomeType, 100> myArray;
public:
    explicit MyClass(std::array<SomeOtherType, 100> initArray);
};

Предполагая, что у класса SomeType есть конструктор, который принимает в качестве аргумента один SomeOtherType, возможно ли инициализировать член constмассив с использованием списка инициализации в конструкторе?Каков синтаксис для этого?

Понятно, что прямая инициализация этого не работает:

MyClass::MyClass(std::array<SomeOtherType, 100> initArray) :
    myArray{initArray} {}

Спасибо!

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Вы можете распаковать аргументы с помощью std::index_sequence и делегировать конструкторы

template<typename Arr, size_t... Is>
MyClass(Arr&& arr, std::index_sequence<Is...>)
  : myArray{arr[Is]...} ()

explicit MyClass(std::array<SomeOtherType, 100> arr) : MyClass(arr, std::make_index_sequence<100>{}) ()
0 голосов
/ 27 ноября 2018

Это возможно.Вам просто нужен маленький вспомогательный шаблон функции, чтобы сделать преобразование для вас.Как то так:

template <class T, class U, size_t N>
std::array<T, N> ArrayConvert(std::array<U, N> const& init)
{
  std::array<T, N> result;
  std::copy(init.begin(), init.end(), result.begin());
  return result;
}

class Foo
{
  std::array<int, 100> myArray;
public:
  template <class U> Foo(std::array<U, 100> const& init)
    : myArray(ArrayConvert<int>(init))
  {
  }
};
0 голосов
/ 27 ноября 2018

Вы можете использовать шаблон переменной:

#include <array>

struct foo
{
    const std::array<int, 10> bar;

    template<typename... T>
    foo(T&&... t)
    : bar({ std::move(t)... })
    {}
};

int main()
{
    foo f{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
}

Или вы можете инициализировать его массивом, переданным конструктору:

#include <array>

struct foo
{
    const std::array<int, 10> bar;

    explicit foo(std::array<int, 10> const &qux)
    : bar{ qux }
    {}
};

int main()
{
    std::array<int, 10> qux;
    foo f(qux);
}

Но эти параметры не учитываютчто вы хотите, чтобы массив SomeOtherType был преобразован в массив SomeType.Сначала я этого не понимал, вот варианты выше.

#include <cstddef>
#include <array>
#include <utility>

struct SomeOtherType{};

struct SomeType {
    SomeType(SomeOtherType) {}
};

struct MyClass
{
    const std::array<SomeType, 100> myArray;

    template<typename T, std::size_t... N>
    MyClass(T&& qux, std::index_sequence<N...>)
    : myArray{ qux[N]... }
    {}

    explicit MyClass(std::array<SomeOtherType, 100> const &qux)
    : MyClass{ qux, std::make_index_sequence<100>{} }
    {}
};

int main()
{
    std::array<SomeOtherType, 100> qux{};
    MyClass foo(qux);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...