Упрощенная версия
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); }
Это не летит, потому что литералы не понимаются в строке, где определен массив. Но функция свободного литерала не может быть перемещена раньше, потому что тогда C не известен.
Есть ли решение для этого гордиева узла, которое не включает в себя добавление вариационных шаблонов или чего-то ужасного в коде?
Проблема на самом деле не в пользовательских литералах, а в том, что std::array
требует полных типов (или действительно, любой constexpr
инициализация делает). Следующий код также не скомпилируется:
#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
};
С ошибками, похожими на (Clang 3.3 SVN здесь):
/ usr / include / c ++ / v1 / array: 136: 16: ошибка: поле имеет неполный тип 'value_type' (он же «С») value_type __elems _ [_ Size> 0? _Size: 1]; ^ t.cpp: 5: 36: note: при создании шаблона класса 'std :: __ 1 :: array' просили здесь статический constexpr std :: array<C, 2> foo {{C ('1'), C ('2')}}; ^ t.cpp: 3: 7: примечание: определение 'C' не завершено до закрытия '}' класс С { ^
Других решений пока нет …