навеяно сообщениями Mishka<T> "Ответ Майерсу 2" и вопросом на Исходниках.ру по поводу возведения в степень.
как народ оценивает мысль переложения вычисления сложных констант на период компилляции? Вот что у меня получилось.
#include <iostream>
typedef unsigned char powered;
//==============================================================================
// вычисление x в степенях 2.
//==============================================================================template < double x, powered y, powered flag >
struct x_pow_2nd
{
static double res;
};
//------------------------------------------------------------------------------template < double x, powered y, powered flag >
double x_pow_2nd< x, y, flag >::res =
x_pow_2nd< x, y/2, flag >::res
* x_pow_2nd< x, y/2, flag >::res;
//==============================================================================
// специализация для случая flag = 0 - res == всегда 1
//==============================================================================template < double x, powered y>
struct x_pow_2nd<x, y, 0>
{
static double res;
};
//------------------------------------------------------------------------------template < double x, powered y >
double x_pow_2nd< x, y, 0 >::res = 1;
//==============================================================================
// специализация для степени 1 (прекращение рекурсии)
//==============================================================================template < double x, powered flag >
struct x_pow_2nd <x, 1, flag >
{
static double res;
};
//------------------------------------------------------------------------------template < double x, powered flag >
double x_pow_2nd< x, 1, flag >::res = x;
//==============================================================================
// специализация для степени 1 (прекращение рекурсии)
//==============================================================================template < double x >
struct x_pow_2nd <x, 1, 0 >
{
static double res;
};
//------------------------------------------------------------------------------template < double x >
double x_pow_2nd< x, 1, 0 >::res = 1;
//==============================================================================
// специализация для степени 0 (прекращение рекурсии)
//==============================================================================template < double x, powered flag >
struct x_pow_2nd <x, 0, flag >
{
static double res;
};
//------------------------------------------------------------------------------template < double x, powered flag >
double x_pow_2nd< x, 0, flag >::res = 1;
//==============================================================================
// основной шаблон.
//==============================================================================template < double x, powered y, powered level = (1 << (sizeof(powered)*8 - 1)) >
struct x_pow_y
{
static double res;
enum { y_and_level = y & level };
};
//------------------------------------------------------------------------------template < double x, powered y, powered level >
double x_pow_y< x, y, level >::res =
x_pow_2nd< x, level, y_and_level >::res
* x_pow_y< x, y, level/2 >::res;
//==============================================================================
// специализация основного шаблона, которая прекращает рекурсию для случая
// level == 0
//==============================================================================template < double x, powered y >
struct x_pow_y< x, y, 0 >
{
static double res;
};
//------------------------------------------------------------------------------template < double x, powered y >
double x_pow_y< x, y, 0 >::res = 1;
//==============================================================================int main(int argc, char* argv[])
{
std::cout << x_pow_y<4.23, 13>::res;
return 0;
}
жаль вот только, что по стандарту нельзя использовать в параметрах шаблонов константы с плавающей точкой, но хоть на gcc такой изврат делается, что приятно.
вот только сложновато вроде, как можно поупростить?
Не по стандарту — это не хорошо. А ты попробуй использовать, например, два int для представления double (int.int), и после переписать шаблоны, может что дельное и выйдет.
MT>Не по стандарту — это не хорошо. А ты попробуй использовать, например, два int для представления double (int.int), и после переписать шаблоны, может что дельное и выйдет.
Пожалуй дождусь для начала комментариев о нужности/полезности этой темы. Принципиально результат получен. Если в результате идиологических споров меня убедят, что направление можно развивать, то можно будет и переделать.
Вот, кстати в соседнем триде очень отрицательный отзыв. А может все это в самом деле извращение и нас лечить надо?
Хотел бы дождаться коментариев других гуру, Андрея Тарасевича, например.
Здравствуйте Mishka<T>, Вы писали:
MT>А ты его напрямую спроси, типа "Андрей, я и Mishka тут фигню на шаблонах написали. Не подскажешь, что теперь с ней делать?" :))) :)))
Здравствуйте Mishka<T>, Вы писали:
ФВ>>Хотел бы дождаться коментариев других гуру, Андрея Тарасевича, например.
MT>А ты его напрямую спроси, типа "Андрей, я и Mishka тут фигню на шаблонах написали. Не подскажешь, что теперь с ней делать?" :))) :)))
В качестве идеи все это интересно только таким же гуру, которые оценят и предложат еще какой-нибудь наворот.
А простым "сермяжным" программистам все это нафиг не надо. Им нужно готовое, законченное, хорошо документированное решение (тот же STL, может быть Boost), которое будет решать > 80% проблем с затратами на освоение этого готового решения < 20%.
Поэтому как только это из идеи перейдет на практику, то это уже будет интересно.
А сейчас ни идея Мишки, ни идея Фролова даже не компилируется на VC (массового компилятора для массовой операционки).
Здравствуйте Флоров В.М., Вы писали:
ФВ>...я птичку нашу попрошу... не обижать.. (с) мультик один ФВ>Ник я конечно сменю, но фамилия у меня все-таки Флоров, а не Фролов.