Литеральная строка компиляции в качестве аргумента шаблона

87
7

Я пытаюсь преобразовать литеральную строку С++ в экземпляр следующего шаблона:


template <char ... C>
struct string_literal {
typedef string_constant type;
static constexpr const char value[sizeof...(C)] = {C...};
constexpr operator const char* (void) const {
return value;
}
};
template <char ... C>
constexpr const char string_literal<C...>::value[sizeof...(C)];

Я придумал эти помощники на основе различных источников для "распаковки" приведенного значения строки в шаблон выше.


template <unsigned N, const char (&S) [N], typename U>
struct selector;

template <unsigned N, const char (&S) [N], unsigned ...I>
struct selector<N, S, index_sequence<I...>> {
using type = string_literal<S[I]...>;
};

template <unsigned N, const char (&S) [N]>
struct unpack {
using type = typename selector<N, S, make_index_sequence<N>>::type;
};


Однако при вызове я получаю ошибку компилятора:


template <unsigned N>
constexpr auto make_string_literal(const char (&s) [N]) {
return unpack<N, s>{}; // Error here
}

constexpr auto literal = make_string_literal("test");
// string_literal<'t','e','s','t','\0'>


Отчеты GCC 4.9+:
ошибка: 'const char (& s) [1]' не является допустимым аргументом шаблона для типа 'const char (&) [1]', поскольку ссылочная переменная не имеет постоянного адреса


Отчеты Clang 3.7.1:
ошибка: аргумент шаблона non-type относится к объекту ', который не имеет привязки


Я пробовал несколько разных подходов, но ошибки в основном одинаковы.
Что мне здесь не хватает?

спросил(а) 2016-02-27T09:38:00+03:00 4 года, 1 месяц назад
1
Решение
51

Это удовлетворительное решение для удовлетворения ваших потребностей?

template <char ... C>
struct string_literal {
static constexpr const char value[sizeof...(C)] = {C...};
constexpr operator const char* (void) const {
return value;
}
void foo() {std::cout << value << '\n';}
};
template <char ... C> constexpr const char string_literal<C...>::value[sizeof...(C)];

template <typename CharT, CharT... Cs>
constexpr string_literal<Cs...> operator ""_create() {
return {};
}

int main() {
string_literal<'t','e','s','t'> s = "test"_create;
std::cout << s << '\n'; // test
s.foo(); // test
}

ответил(а) 2016-04-01T20:02:00+03:00 4 года назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема