Инициализировать массив constexpr с пользовательским литералом

Упрощенная версия

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 не известен.

Есть ли решение для этого гордиева узла, которое не включает в себя добавление вариационных шаблонов или чего-то ужасного в коде?

2

Решение

Проблема на самом деле не в пользовательских литералах, а в том, что 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' не завершено до закрытия '}'
класс С {
^
3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector