Cannot construct constexpr array from braced-init-list

后端 未结 2 774
说谎
说谎 2021-02-05 15:30

I\'ve implemented a constexpr array like this:

template 
class const_array {
  const T* p;
  unsigned n;
public:
  template 

        
相关标签:
2条回答
  • 2021-02-05 15:46

    The problem was that you cannot imbue the constant nature of the pointer to T in the inner template through the outer template's T parameter.

    template <typename T> class const_array {
        const T * p;
        unsigned n;
    public:
        template <unsigned N>
            constexpr const_array(const T(& a)[N]): p(a), n(N) { }
    };
    
    int main(int argc, char* argv[]) {
        constexpr const_array<double> ca{(const double []) { 1., 2. }};
        return 0;
    }
    

    I tried a few dozen permutations to get rid of the cast without success.

    0 讨论(0)
  • 2021-02-05 15:48

    The compiler is complaining that the initializer of a.p is not a constant expression. It's failing §5.20/5.2:

    if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value

    In other words, only pointer values known to the linker are valid constants. (Also, in your example the pointer is dangling.)

    The first static_assert doesn't trip this because p is discarded and the value of n is a constant expression. Constant expressions may have non-constant subexpressions.

    This works:

    static constexpr double arr[] = { 1.,2.,3. };
    constexpr const_array<double> a{ arr };
    static_assert( a.size() == 3 );
    

    Credit to @Jarod42 for pointing out the issue in the comments.

    0 讨论(0)
提交回复
热议问题