簡體   English   中英

C++ 對象數組,帶有 const 初始值設定項列表

[英]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};
}

查看關於 coliru工作代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM