3

I wanted to have integers converted to string literals at compile time in C++17. I used this perfect solution.

Anyways, the problem with this solution is that I am not able to assign the result of num_to_string to a constexpr char []:

static constexpr const char number_str[] = num_to_string<5683>::value; // ERROR

The error is:

error: initializer fails to determine size of ‘number_str’

error: array must be initialized with a brace-enclosed initializer

I solved the problem in such a way that I ignored "my requirement" that the number_str must be an array so I've made it a pointer:

static constexpr const char *number_str{detail::num_to_string<5683>::value};

And that's all good, BUT: :)

I'm still curious to see whether it is possible, so my idea is to somehow copy-assign an array to another one.


Having an array and pointers:

static constexpr char first_array[] = "aaaabbbbcccc";

I would like to copy initialize the second array, like that:

static constexpr char second_array[] = copy_the(first_array);
  1. I can't do it using function templates, because functions can't return C-arrays.
  2. Using structs for folding the arrays will result in returning an object, which could be then assigned to the array, but you can't copy-assign arrays.
  3. I tried to use fold expressions with template aliases and with std::integer_sequence, e.g.:
template <auto Ptr, std::size_t... I>
using explode_array_impl = (Ptr[I], ...);

template <auto Ptr, std::size_t N>
using explode_array = explode_array_impl<Ptr, std::make_index_sequence<N>>;

But it won't work because a template alias expects type-id on the right side of =.

Is there a way to make it possible to somehow copy-assign an array to another one?

Community
  • 1
  • 1
K. Koovalsky
  • 596
  • 4
  • 17
  • 3
    What about using a wrapping `struct`/`class` (I suggest a `std::array`, that is lightweight and `constexpr` compatible) for the destination (for `numer_str`)? – max66 Nov 23 '19 at 14:08
  • 1
    @max66 I thought about it and that is a good solution. One needs to remember about the trailing `\0` and decide whether to include it in the `std::array` or not. But still the question is more related to curiosity and it doesn't answer the question directly. – K. Koovalsky Nov 23 '19 at 15:18
  • Your question is a perfectly legit question; but I suppose there isn't a satisfactory solution. If I'm not wrong, `std::array` was introduced also to resolve this sort of problems. Using a `std::array` of `char`s... about the trailing zero... my 2 cent: add it, so you can use the value returned by `data()` (a `char const *`, potentially a `constexpr char const *`) approximately as you use your `number_str`. – max66 Nov 23 '19 at 18:05
  • Yeah, I think I need to change my mindset and prevent myself from using `char[]` and use `std::array` instead. Maybe it would be good to not get an answer, so other people could also reconsider using `std::array` instead of raw pointers and raw arrays. :D – K. Koovalsky Nov 23 '19 at 18:10
  • In the case that already works using a pointer, you could use a reference to the array (via `auto&` to capture the size). I don’t know if that counts. – Davis Herring Nov 23 '19 at 18:13

1 Answers1

0

You can't initialize an array variable from another array, only from a brace-enclosed list.

However, you can create a structured binding (https://godbolt.org/z/VUnrYT):

struct X {
  int x[3];
};

constexpr X func() {
  X x{{0, 1, 2}};
  return x;
}

auto [y] = func();
static_assert(std::is_same<decltype(y),int[3]>::value);

Anthony Williams
  • 66,628
  • 14
  • 133
  • 155