如何使用std::array构造函数参数进行常量std::array成员的列表初始化 C++

4
假设我们有以下的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} {}

谢谢!


2
你知道如果你的类有一个const成员,它将无法被复制吗? - Swordfish
如果您正在使用c++11(或更新版本),请查阅std::initializer_list的文档。如果您正在使用GCC编译,您可能会发现这篇文章很有用:https://dev59.com/h2sy5IYBdhLWcg3w-i7h - HappyKeyboard
@Swordfish:感谢你提醒,对于我目前的使用情况来说应该不是问题,但我会记住这一点以备将来之需。 - Embedder
@HappyKeyboard:谢谢,我会看一下std::initializer_list。也很好知道在使用std::array和gcc时需要双花括号! - Embedder
3个回答

4
您可以使用可变参数模板:
#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);
}

1
你可以使用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

这是可能的。您只需要一个小的帮助函数模板来为您进行转换。类似这样:

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))
  {
  }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接