0

I have a class that can be constexpr constructed. I use it do alter some string literals at compile time. In this contrived example you can see that the constexpr constructor is called which will then process a local member data_. But how do I get the data_ out finally? My approach doesn't seem to work:

(Demo)

#include <cstdio>
#include <cstddef>

template <const char* S>
struct cxprstring
{
    constexpr cxprstring() : data_{S} {
        // ...
        // (further processing of data_)
    }

    constexpr static const char value[] = cxprstring<S>{}.data_;

    char data_[] = {};
};

template <const char* S>
constexpr const char format_view[] = cxprstring<S>::value;

constexpr const char a[] = "hello ";

int main()
{
    printf("%s\n", format_view<a>);
}

It yields the following errors:

<source>:12:59: error: initializer fails to determine size of 'cxprstring<S>::value'
   12 |     constexpr static const char value[] = cxprstring<S>{}.data_;
      |                                           ~~~~~~~~~~~~~~~~^~~~~
<source>:18:53: error: initializer fails to determine size of 'format_view<S>'
   18 | constexpr const char format_view[] = cxprstring<S>::value;
      |                                                     ^~~~~

How can I make it work?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
glades
  • 3,778
  • 1
  • 12
  • 34
  • It isn't clear what's being attempted here. You're using a lot of C-style arrays in ways that don't really make sense (ie: the compiler doesn't have any array sizes). – Nicol Bolas Aug 11 '22 at 15:19
  • @NicolBolas The compiler should be able to determine the array size if the rightside is actually constexpr. Compare `constexpr const char a[] = "hello ";` which works just fine. I'm trying to achieve the same for my code. – glades Aug 11 '22 at 15:21
  • "*The compiler is able to determine the array size if the rightside is actually constexpr.*" No, that's not how it works. The arrays size can be determined if the RHS is an array type. `{}` is not an array, and this is what you use to initialize the `data_` member. `S` is a pointer, not an array, so even if you initialized `data_` with `S`, there is no array size to apply to it. – Nicol Bolas Aug 11 '22 at 15:22
  • @NicolBolas Ahh I understand! I guess I figured it out. I need to constexpr construct the object itself with static storage duration, then I can access the data :) – glades Aug 11 '22 at 15:28

1 Answers1

1

Unsized arrays cannot be non-static data members of a type. Ever.

Even if they could, the size it would undoubtedly have to be deduced by the default member initializer. Which in your case is {}, so the size would be 0. Which is not allowed.

And even if the size could be deduced by the constructor instead... S is a pointer. The compiler does not know how many characters it points to. So there is no way to get its size.

This method of doing whatever it is you're trying to do is non-viable.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982