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.

2
  • GCC 4.x.x is way, way too old to use modern C++ idioms. Commented Oct 4, 2018 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. Commented Oct 5, 2018 at 14:08

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.