Reputation: 19320
Simplified version
class C {
public:
static constexpr std::array<C, 2> foo {{"1"_C, "2"_C}};
int x;
constexpr C(char c) { x=c; }
}
constexpr C operator"" _C(const char * str, size_t n) { return C(*str); }
This doesn't fly, because the literals are not understood at the line where the array is defined. But the free literal function can't be moved earlier because then C isn't known.
Is there a solution to this Gordian knot that doesn't involve adding variadic templates or something horrid like that into the code?
Upvotes: 2
Views: 685
Reputation: 131799
The problem doesn't really lie with user-defined literals, but with the fact that std::array
requires complete types (or really, any constexpr
initialization does). The following code will also fail to compile:
#include <array>
class C {
public:
static constexpr std::array<C, 2> foo {{C('1'), C('2')}};
int x;
constexpr C(char c) : x(c) {} // please use a mem-initializer-list
};
With errors similar to (Clang 3.3 SVN here):
/usr/include/c++/v1/array:136:16: error: field has incomplete type 'value_type' (aka 'C') value_type __elems_[_Size > 0 ? _Size : 1]; ^ t.cpp:5:36: note: in instantiation of template class 'std::__1::array' requested here static constexpr std::array<C, 2> foo {{C('1'), C('2')}}; ^ t.cpp:3:7: note: definition of 'C' is not complete until the closing '}' class C { ^
Upvotes: 3