Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
#include <iostream>
template <int n>
struct Solution
{
static const int count = Solution<n / 10>::count + 1;
static const int sum = Solution<n / 10>::sum + n % 10;
static const int last = n % 10;
static const int first = Solution<n / 10>::first;
};
#define DECLARE_ONE_DIGIT_SOLUTION(n) template <>\
struct Solution<n>\
{\
static const int count = 1;\
static const int sum = n;\
static const int last = n;\
static const int first = n;\
};
DECLARE_ONE_DIGIT_SOLUTION(0)
DECLARE_ONE_DIGIT_SOLUTION(1)
DECLARE_ONE_DIGIT_SOLUTION(2)
DECLARE_ONE_DIGIT_SOLUTION(3)
DECLARE_ONE_DIGIT_SOLUTION(4)
DECLARE_ONE_DIGIT_SOLUTION(5)
DECLARE_ONE_DIGIT_SOLUTION(6)
DECLARE_ONE_DIGIT_SOLUTION(7)
DECLARE_ONE_DIGIT_SOLUTION(8)
DECLARE_ONE_DIGIT_SOLUTION(9)
int main()
{
const int number = 1024; // <-- то самое число a
std::cout << "Number of digits: " << Solution<number>::count << std::endl;
std::cout << "Sum: " << Solution<number>::sum << std::endl;
std::cout << "Last digit: " << Solution<number>::last << std::endl;
std::cout << "First digit: " << Solution<number>::first << std::endl;
return 0;
}
Это один из ответов к слезной просьбе какого-то школьника (студента) выполнить за него д/з на С++ в разделе development форума на ЛОРе. Такую программу нарочно хрен напишешь.
Само задание: «Дано натуральное число а (a≤100). Напишите программу, определяющую количество цифр в этом числе, сумму его цифр, выводящую на экран первую и последнюю цифру через два пробела».
А в задании и не написано про темплэйты. Если школьник изъебывается с тем, что не знает и не давали, это вина препода?
Кстати, и не школьник это писал -- это ответ на его просьбу. Так что школота в этот раз только свою лень показала.
Проблема в том, что программирование на философском факультете преподаёт не философ, а человек с киберфака или мехмата. И на философию у него должен быть иммунитет.
буквально на днях где-то в блогах читал что МС компилятор для флоатов разворачивает только двойную вложенность констант, для тройной уже вставляет код вычисления...
в гсс с такой проблемой сталкивался сам год назад, в жизни до main были неинициализированные константы...
приведу псевдокод еще раз
// c1.cpp
const int& some_val_ref = Some_template<param>::value;
// c2.cpp
extern const int& some_val_ref;
некоторый класс в жизни до main обращался к этой переменной и получал в ответ 0, при этом в main этот же код читал правильное значение...
я не разбирался где именно проблема... я лишь вынес урок что const int не всегда компайл тайм переменная в отличии от enum{ some_const }; которая в случае невозможности вычисления в компайл тайм, выдаст ошибку компиляции...
я использовал ссылку на эту переменную... до определенного момента из переменной читался 0, потом оказалось что она просто вычислялась позже чем я ее пытался читать... компилятор GCC 4.0 из iPhone SDK
Ну это тоже говнокодовость, нафига ссылку давать на POD тип? Очень сильно попахивает. При условии, что передача POD типов очень хорошо оптимизируется, ну а так же ссылка приводит к разыменованию переменной, что и привело к тому, что переменная покинула пределы compile-time.
одна из библиотек для линковки требовала несколько констант, которые она принимала по ссылке, типа так
extern const int& use_some;
extern const bool& enable_something;
Ну вот это жесть, хотя для objective c это может и в порядке вещей. Я бы пальцы вырвал такому разработчику, кто придумал передавать так данные в либу)))
>Инициализация статических интегральных типов возможна внутри класса.
Конечно, только не во всех компиляторах. Например майкрософстская 2008 студия - сольёт.
если объявлять константы через const int то где то в СPP файле нельзя будет сделать так
int array[Solution<10>::count];
метод с enum лишен этого недостатка...
Надо мне глянуть на STL из MS VS. По моему там конструкций в определениях классов, вида static const * = *; нет. Только через enum.
Жалко MS VS дома не стоит...
Угу, как раз недавно играл в такую. Если персонаж на рассвете посмотрит вправо и немного вверх, игра превращается в слайд-шоу. По прошествию 3 патчей - не исправлено.
это правда... и это печально...
только говнокодят обычно в ноч перед дедлайном, а потом живут по принципу "работает - не трогай"...
обидно, что можно жить по другому, но в это мало кто верит...
в геймдеве очень много data driven кода, и иные подходы считаются очень говнокодными.
время программистов дороже времени геймдизайнеров и артистов, поэтому все стараются выносить из кода в данные...
отсюда любовь ко всяким луа, хмл, и тп...
Верно, специализация для 10 цифр понадобилась из-за first. Ваш вариант не работает для очень больших чисел (возможно переполнение в 10 * number) -- следует использовать number / solution<number/10>::power_10.
Ну и использовать enum вместо static const int не нужно.
сначала надо человека сям научить и процедруному подходу
потом грузить неокрепший мозг темплейтами
Кстати, и не школьник это писал -- это ответ на его просьбу. Так что школота в этот раз только свою лень показала.
Вычисления в компайл-тайме - уважаю!
ЗЫ: любопытно, примут ли работу у того школьника?
enum
{
count = Solution<n / 10>::count + 1,
sum = Solution<n / 10>::sum + n % 10,
last = n % 10,
first = Solution<n / 10>::first,
};
компилятор может забить на разворачивание интов и тупо вставить код который их вычисляет...
в гсс с такой проблемой сталкивался сам год назад, в жизни до main были неинициализированные константы...
Не у поминайте её всуе.
приведу псевдокод еще раз
// c1.cpp
const int& some_val_ref = Some_template<param>::value;
// c2.cpp
extern const int& some_val_ref;
некоторый класс в жизни до main обращался к этой переменной и получал в ответ 0, при этом в main этот же код читал правильное значение...
extern const int& use_some;
extern const bool& enable_something;
В стандарте до С++0х не с компилируется.
По крайней мере майкрософсткий компилятор до 2010 студии это делать не будет.
Инициализация статических интегральных типов возможна внутри класса.
Например:
Зато другая и более надёжная половина библиотек использует заместо этого приёма enum.
Конечно, только не во всех компиляторах. Например майкрософстская 2008 студия - сольёт.
работает
И при зависимости от шаблона тоже работает?
int array[Solution<10>::count];
метод с enum лишен этого недостатка...
Интересно, и как STL, а тем более Boost, где такое применяется в шерсть и в гриву, чувствуют себя на таких компиляторах?
Но немалая часть enum употреблена по делу, для перечислений, или в комментариях.
То есть в большинстве случаев может быть:,а не:
Да что я тут грепом машу -- см. 9.4.2.
Жалко MS VS дома не стоит...
паскалисты верят что именно уголочки делают С++ настолько крутым...
там действительно допустимо превратить код в кусок говна ради скорости
там надо к кристмасу выпустить
только говнокодят обычно в ноч перед дедлайном, а потом живут по принципу "работает - не трогай"...
обидно, что можно жить по другому, но в это мало кто верит...
тоже явно не в коде дело 😀
время программистов дороже времени геймдизайнеров и артистов, поэтому все стараются выносить из кода в данные...
отсюда любовь ко всяким луа, хмл, и тп...
в хорошем энтерпрайзе тоже есть DSL
нужна специализация только для нуля. потом last и надо выкинуть из шаблона first. вместо него ввести степень 10.
Ну и использовать enum вместо static const int не нужно.