1

I'm trying to write a C++ container that wraps around raw C-arrays. I would like to supply some constexpr functionality, but am running into a few small issues with the constructor. I seem to be un-able to pass an r-value C-array in constexpr context. Here is a "bare-bones" example of what I'm tying to do:

#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";
}

Specifically, I'm looking for a way to pass a C-array to a constexpr constructor without having to manually pass in a size parameter or l-value.

A few things to note:

  • I am using GCC 4.8.5, and can not upgrade at the moment
  • Compiling with -std=c++11, and can not change that at the moment
  • I found this question as a reference, but it does not address my constexpr needs

Maybe there's a way to do this with variadic templates or something, but I seem to be stuck at the moment. C++14 would be really nice, as I could just use constexpr std::initializer_list, but alas, I don't have that option right now.

zeus_masta_funk
  • 1,388
  • 2
  • 11
  • 34
  • GCC 4.x.x is way, way too old to use modern C++ idioms. –  Oct 04 '18 at 22:55
  • @NeilButterworth I'm very aware, and came to this job from a GCC 7.x compiler, so I already feel severely limited. However, 4.8.5 is fully C++11 compliant at least, and we have plans to upgrade in the near future - but this development is happening now. – zeus_masta_funk Oct 05 '18 at 14:08

1 Answers1

2

The issue here is that the address of a temporary object is not a permitted result of a constant expression (reference). Therefore, you can't construct a constexpr object that stores within itself the address of a temporary array. If you want to be able to wrap a C-style array, maybe you should write another class that copies its elements. That's something that should work in a constexpr context.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312