Здравствуйте, ankorol, Вы писали:
ТКС>>Exp10 у него, естественно, рекурсивная. Не рекурсивно такие вещи на шаблонах не делаются.
A>Ну это вспомогательный класс. Его тоже можно заполнить специализациями вручную до каких-то разумных приделов.
С тем же успехом можно и все нужные строки специализациями задать.
A>Но согласен очень много чего в метапрограммировании на С++ рекурсивное...
Вообще-то ни много, ни мало, а любые вычисления во время компиляции
Просто других средств для вычислений нету — только рекурсия для повторения и специализация для ветвления. Дальше можно уже как в MPL через них выражать другие сущности.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, ankorol, Вы писали:
A>Здравствуйте, Alexey F, Вы писали:
АF>>Может, int на unsigned сменить?
A>Да, надо бы сменить... или допилять что-бы отрицательные корректно обрабатывались
Ровно как и не забыть про проблему переполнения
Здравствуйте, ankorol, Вы писали:
A>Можно ли как-то преобразовать целое в строку во время компиляции?...
Азарт разыгрался, захотелось решить задачку без сторонних библиотек. В этой версии отбрасываются незначащие нулевые разряды и правильно обрабатываются отрицательные числа и нуль. Реализация, конечно, несколько сложнее, чем
здесьАвтор: rg45
Дата: 24.12.09
:
enum Signs { negative, positive };
template<int n> struct Abs { static const unsigned value = n < 0 ? -n : n; };
template<int n> struct Sign { static const Signs value = n < 0 ? negative : positive; };
template<unsigned n> struct DigitsCount { enum { value = DigitsCount<n/10>::value + 1 }; };
template<> struct DigitsCount<0> { enum { value = 0 }; };
template<unsigned n, int pos, bool outOfRange> struct CheckedLittleEndianSymbolAt { static const char value = 0; };
template<unsigned n, int pos> struct CheckedLittleEndianSymbolAt<n, pos, false>
{ static const char value = CheckedLittleEndianSymbolAt<n / 10, pos - 1, false>::value; };
template<unsigned n> struct CheckedLittleEndianSymbolAt<n, 0, false> { static const char value = '0' + n%10; };
template<unsigned n, int pos> struct LittleEndianSymbolAt : CheckedLittleEndianSymbolAt<n, pos, pos < 0> { };
template<Signs sign, unsigned absValue, int pos> struct SymbolOfSignedAt;
template<unsigned n, int pos> struct SymbolOfSignedAt<negative, n, pos> : SymbolOfSignedAt<positive, n, pos - 1> { };
template<unsigned n> struct SymbolOfSignedAt<negative, n, 0> { static const char value = '-'; };
template<unsigned n, int pos> struct SymbolOfSignedAt<positive, n, pos> : LittleEndianSymbolAt<n, DigitsCount<n>::value-pos-1> { };
template<> struct SymbolOfSignedAt<positive, 0, 0> { static const char value = '0'; };
template<int n, int pos> struct SymbolAt : SymbolOfSignedAt<Sign<n>::value, Abs<n>::value, pos> { };
template<int n> struct IntToString { static const char value[]; };
template<int n> const char IntToString<n>::value[] =
{
SymbolAt<n,0>::value, SymbolAt<n,1>::value, SymbolAt<n,2>::value, SymbolAt<n,3>::value,
SymbolAt<n,4>::value, SymbolAt<n,5>::value, SymbolAt<n,6>::value, SymbolAt<n,7>::value,
SymbolAt<n,8>::value, SymbolAt<n,9>::value, SymbolAt<n,10>::value, SymbolAt<n,12>::value,
};
Теперь нужно убедиться, что мы получаем эти строки именно во время компиляции. Для этого достаточно проверить, что мы можем этими строковыми значениями параметризовать шаблоны:
#include <iostream>
template<const char* str>
struct CompileTimeString
{
static void print() { std::cout << str << std::endl; }
};
int main()
{
CompileTimeString<IntToString<123>::value>::print(); //Output: 123
CompileTimeString<IntToString<0>::value>::print(); //Output: 0
CompileTimeString<IntToString<-1234567>::value>::print(); //Output: -1234567
}
Здравствуйте, ankorol, Вы писали:
A>Здравствуйте, nen777w, Вы писали:
N>>N>>#define I2S( val ) #val
N>>const char *p = I2S(45);
N>>
N>>Так? Или Я вопроса не понял.
A>A>const int N=45;
A>const char *p = I2S(N);// p =="N" а хочется 45
A>
тут препроцессор работает, до компилятора дело не доходит, придется так:
#define N 45
Здравствуйте, труженик села, Вы писали:
ТС>ТС>#define N 45
ТС>
Но ведь мы пытаемся писать на С++
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Здравствуйте, ankorol, Вы писали:
A>Спасибо! Супер! Мне нехватало этого шага с инициализацией строки символами через запятую, всё пытался конкатенировать строки. Танцевальные движения с бубном попробую сам придумать.
А это разве получится в #pragma message запихнуть?
Здравствуйте, remark, Вы писали:
R>А это разве получится в #pragma message запихнуть?
R>
Нет, но целое в строку переводит!
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>