如何使用 std::array 构造函数参数 C++ 列表初始化 const std::array 成员
How to list-initialize a const std::array member using a std::array constructor argument C++
假设我们在 C++11 或更高版本中有以下 class:
class MyClass {
private:
const std::array<SomeType, 100> myArray;
public:
explicit MyClass(std::array<SomeOtherType, 100> initArray);
};
假设 class SomeType 有一个构造函数,它接受一个 SomeOtherType 作为参数,是否可以在构造函数中使用列表初始化来初始化 const 成员数组?这样做的语法是什么?
很明显,直接这样初始化是行不通的:
MyClass::MyClass(std::array<SomeOtherType, 100> initArray) :
myArray{initArray} {}
谢谢!
您可以使用可变参数模板:
#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);
}
您可以使用 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>{}) ()
这是可能的。你只需要一个小辅助函数模板来为你做转换。像这样:
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))
{
}
};
假设我们在 C++11 或更高版本中有以下 class:
class MyClass {
private:
const std::array<SomeType, 100> myArray;
public:
explicit MyClass(std::array<SomeOtherType, 100> initArray);
};
假设 class SomeType 有一个构造函数,它接受一个 SomeOtherType 作为参数,是否可以在构造函数中使用列表初始化来初始化 const 成员数组?这样做的语法是什么?
很明显,直接这样初始化是行不通的:
MyClass::MyClass(std::array<SomeOtherType, 100> initArray) :
myArray{initArray} {}
谢谢!
您可以使用可变参数模板:
#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);
}
您可以使用 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>{}) ()
这是可能的。你只需要一个小辅助函数模板来为你做转换。像这样:
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))
{
}
};