![](/img/trans.png)
[英]C++ overload constructor with const array and initializer_list
[英]C++ array of objects with const initializer list
我有一些這樣的代碼:
class MyObject {
private:
int x;
public:
MyObject(int x) : x(x) {}
};
我想初始化 5 個MyObject
實例。 我知道我可以用 g++ 8.3.0 做到這一點。
MyObject obj_array[5]{1, 2, 3, 4, 5};
但是,我無法做到這一點:
const int myInts[5] = {1, 2, 3, 4, 5};
MyObject obj_array[5](myInts);
有什么方法可以使第二種初始化方法(使用 const 整數數組使用初始化列表構造函數初始化對象數組)工作? 問題是我們有一個特殊的編譯器框架,它不允許動態內存或大多數 STL 數據類型,例如vector
。
不漂亮,但這似乎有效:
const int myInts[5] = { 1, 2, 3, 4, 5 };
MyObject obj_array[5] = {myInts[0], myInts[1], myInts[2], myInts[3], myInts[4]};
如果我們正在做丑陋的解決方案,這里有一個具有可擴展性的解決方案:
#define LIST { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
const int myInts[] = LIST;
MyObject obj_array[] = LIST;
#undef LIST
不是真的,因為當原始數組類型用少於它的表達式計數初始化時,對象會被默認初始化。
但是你可以做的一件事是創建你自己的類似數組的類模板:
#include <cstddef>
#include <type_traits>
#include <initializer_list>
#include <utility>
#include <iterator>
template <std::size_t N>
class MyObjectArray
{
public:
using array_type = MyObject[N];
template <typename T, typename Enable =
std::enable_if_t<std::is_convertible_v<T, int>>>
MyObjectArray(T (&arr)[N]);
template <typename T = int, typename Enable =
std::enable_if_t<std::is_convertible_v<T, int>>>
MyObjectArray(std::initializer_list<T> il);
template <typename InputIter, typename Enable =
std::enable_if_t<std::is_convertible_v<
typename std::iterator_traits<InputIter>::reference, int>>>
MyObjectArray(InputIter start, InputIter end);
operator array_type& () noexcept { return m_array; }
operator const array_type& () const noexcept { return m_array; }
private:
template <std::size_t... I, typename InputIter>
MyObjectArray(std::index_sequence<I...>, InputIter iter)
: m_array{ (static_cast<void>(I), *iter++) ... } {}
static std::make_index_sequence<N> check_count(std::size_t n) {
if (n != N)
throw std::invalid_argument(
"Incorrect number of elements initializing MyObjectArray");
// Or if exceptions not supported, some other error reporting
// mechanism and abort.
return {};
}
MyObject m_array[N];
};
template <std::size_t N>
template <typename T, typename Enable>
MyObjectArray<N>::MyObjectArray(T (&arr)[N])
: MyObjectArray(std::make_index_sequence<N>{}, arr) {}
template <std::size_t N>
template <typename T, typename Enable>
MyObjectArray<N>::MyObjectArray(std::initializer_list<T> il)
: MyObjectArray(check_count(il.size()), il.begin()) {}
template <std::size_t N>
template <typename InputIter, typename Enable>
MyObjectArray<N>::MyObjectArray(InputIter start, InputIter end)
: MyObjectArray(check_count(std::distance(start, end)), start) {}
這可以像這樣使用:
int main()
{
const int myInts[5] = {1, 2, 3, 4, 5};
MyObjectArray obj_array(myInts);
MyObjectArray<5> a2 = {3, 4, 5, 6, 7};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.