Законно ли в c ++ конструировать элементы массива, вызывающие в цикле новый, а не новый []? - PullRequest
1 голос
/ 30 октября 2019

Я пишу упаковщик массива в C ++ (например, std::array). Мотивация состояла в том, чтобы сделать массив-оболочку производной интерфейса. Это позволяет передавать массивы в функции, не делая их шаблонными (через интерфейс). Способ его реализации выглядит немного подозрительно, поэтому я хочу спросить, является ли приведенный ниже код законным в C ++ или нет? В примере показан способ использования членов объединения, я попытался сделать наименьший пример, чтобы интерфейса и других вещей здесь не было. Основная проблема заключается в использовании членов профсоюза таким образом. Причина, по которой я это делаю, состоит в том, чтобы сделать возможным создание массива типов без c-tor по умолчанию (к сожалению, в этом примере это тоже не показано).

template<typename T, size_t N>
class Array
{
    public:

    Array() : 
        m_data( m_originalObjects ),
        m_len(N),
        m_place()
    {        
        for( decltype(N) i = 0; i < N; i++ )
        {
            new( &m_data[i] )T();
        }
    }
        //c-tor to objects without default c-tor
        template<typename ... TCon>
        Array( TCon && ... values ) :
            m_data( m_originalObjects ),
            m_len(N),
            m_originalObjects{ static_cast<T>(values)... }
        {
        }

    private:

    T * m_data = nullptr;
    size_t m_len = 0;

    union
    {
        char m_place[sizeof(T) * N];
        T m_originalObjects[N];
    };
};

1 Ответ

0 голосов
/ 30 октября 2019

Проблема решена, я ожидаю, что наличие массива типов c-стиля без c-tors по умолчанию в качестве члена класса приведет к неудачной компиляции, поэтому я использовал union, чтобы «исправить» эту проблему. Правда в том, что такой проблемы нет, спасибо @sebrockm за то, что открыли мне глаза. Следующий код - это то, что мне действительно нужно


template<typename T, size_t N>
class Array
{
    public:

    Array() : 
        m_data( m_originalObjects ),
        m_len(N),
        m_originalObjects{}
    {        
    }

    //конструктор с параметрами
    template<typename ... TCon>
    Array( TCon && ... values ) :
        m_data( m_originalObjects ),
        m_len(N),
        m_originalObjects{ static_cast<T>(values)... }
    {
    }

    private:

    T * m_data = nullptr;
    size_t m_len = 0;

    T m_originalObjects[N];
};
...