Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22463

Portable way to declare constexpr array from non-type template arguments

$
0
0

I'm using this approach for a while to do some compile-time c-string manipulations:

template<char... args> struct String {static const char data[sizeof...(args)+1];};
template<char... args> constexpr const char String<args...>::data[sizeof...(args)+1] = {args...,'\0'};

It works well on all c++11-compliant compilers, however I recently found out that clang does not treat accessing data members as a constexpr constants:

enum Foo {
    Bar = String<'f','o','o'>::data[1]
    // read of non-constexpr variable 'data' is not allowed in a constant expression (clang)
    // works fine (gcc)
};

However, if I rewrite my struct like that:

template<char... args> struct String {static constexpr const char data[sizeof...(args)+1] = {args...,'\0'};};

It would work on both gcc and clang.

The problem is, 2nd approach works only on c++17, and I'd like to have it at least c++14-compatible. Is there any way?

Also would be nice to find out which compiler is right in this case and why. I've searched for specifications but did not find any reasons why 1st approach should not be constexpr.


Viewing all articles
Browse latest Browse all 22463