Я пробовал следующий код в GCC 4.8:
#include <iostream>
using namespace std;
template <typename T, T... vs>
struct integral_list {
typedef T elem_type;
};
template <typename T, T... vs>
struct gen_array {
static const T data[sizeof...(vs)];
};
template <typename T, T... vs>
const T gen_array<T, vs...>::data[sizeof...(vs)] = { vs... };
template <char... cs>
constexpr auto operator "" _lit() -> integral_list<char, cs...> {
return declval<integral_list<char, cs...>>();
}
int main() {
int (& data)[4] = gen_array<char, decltype("abcd"_lit)>::data;
for (int i = 0; i < 4; ++i)
cout << data[i] << endl;
}
и получил
tester.cpp: 21: 48: ошибка: невозможно найти оператор строкового литерала
оператор «» _lit «с аргументами» const char [5] «,» unsigned int «
в то время как C ++ 11 Standard говорит
13.5.8.5: Объявление шаблона литерального оператора должно иметь пустое предложение-объявление-параметра, а его список-параметра-шаблона должен иметь один шаблон-параметр, который представляет собой нетипизированный пакет параметров шаблона (14.5.3) с элементом наберите char.
Так что либо я не разобрался в стандарте, либо GCC идет странно.
Не могли бы вы помочь мне решить эту дилемму?
Если нет, есть ли другой способ реализовать преобразование строкового литерала в список аргументов шаблона переменной?
Вы не можете использовать шаблоны литеральных операторов со строковыми литералами, только с числовыми литералами.
§ 2.14.8 пункт 5:
Если L является определяемым пользователем строковым литералом, пусть str будет литералом без его ud-суффикса, и пусть len будет количеством единиц кода в str (т.е. его длина исключает завершающий нулевой символ). Буква L трактуется как вызов формы
operator "" X (str , len)
Тем не менее, можно сделать некоторые вычисления во время компиляции со строкой аргумента. Тривиальный пример, возможно полезный в качестве модели:
#include <iostream>
constexpr unsigned long operator"" _mylong(const char* s, size_t l) {
return l == 0 ? 0UL : (s[l - 1] - '0') + 10 * operator"" _mylong(s, l - 1);
}
int main() {
std::cout << "1492888888888888"_mylong << std::endl;
return 0;
}
В gcc 4.9 он доступен (вам, вероятно, понадобится скомпилировать его из SVN)
http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00998.html