Как передать временный массив C в контейнер constexpr - PullRequest
0 голосов
/ 05 октября 2018

Я пытаюсь написать контейнер C ++, который оборачивает необработанные C-массивы.Я хотел бы предоставить некоторые constexpr функциональные возможности, но я столкнулся с несколькими небольшими проблемами с конструктором.Кажется, я не могу передать C-массив r-значения в контексте constexpr.Вот простой пример того, что я хочу сделать:

#include <iostream>
#include <type_traits>

namespace TEST
{
class Container
{
public:
    using size_type = std::size_t;
    using value_type = uint32_t;
    using const_reference = const value_type&;
    using const_pointer = const value_type*;

    template<size_type SIZE>
    constexpr Container(const value_type (&data)[SIZE])
        : _arr(data), _len(SIZE) {}

    constexpr Container(const_pointer data, size_type len)
        : _arr(data), _len(len) {}

    constexpr size_type size() const
        {return _len;}

    constexpr const_reference operator[](size_type idx) const
        { return _arr[idx]; }

private:
    const_pointer _arr;
    size_type _len;
};
}

int main()
{
    using X = uint32_t[3];
    //Comment/Uncomment the following line to observe error:
    // constexpr TEST::Container mycontainer1(X{4, 5, 6});

    static constexpr uint32_t arr2[] = {1, 2, 3};
    constexpr TEST::Container mycontainer2(arr2, 3);


    constexpr int x = mycontainer2[0];
    std::cout << "Hello, " << x << "!\n";
}

В частности, я ищу способ передачи массива C в конструктор constexpr без необходимостивручную передать параметр размера или l-значение.

Несколько замечаний:

  • Я использую GCC 4.8.5 и не могу обновить в данный момент
  • Компилируется с -std=c++11, и не может изменить это на данный момент
  • Я нашел этот вопрос как ссылка , но он не отвечает на мои constexpr потребности

Может быть, есть способ сделать это с помощью шаблонов с переменными значениями или что-то в этом роде, но я сейчас застрял.C ++ 14 был бы действительно хорош, поскольку я мог бы просто использовать constexpr std::initializer_list, но, увы, у меня сейчас нет такой опции.

1 Ответ

0 голосов
/ 05 октября 2018

Проблема здесь в том, что адрес временного объекта не является разрешенным результатом константного выражения ( ссылка ).Следовательно, вы не можете создать constexpr объект, который хранит в себе адрес временного массива.Если вы хотите иметь возможность оборачивать массив в стиле C, возможно, вам следует написать другой класс, который копирует его элементов.Это то, что должно работать в контексте constexpr.

...