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.