Здесь при расчёте factorial<5> последовательно инстанциируются шаблоны factorial<5>, factorial<4>, factorial<3>, factorial<2>, factorial<1> и factorial<0>. Некоторые умные люди говорят, что это бьёт по времени компиляции (точнее по памяти компилятора). На каждый инстанс надо завести память и эту память компилятор освободить никак не сможет до окончания компиляции. С другой стороны, скорость вычислений потенциально может вырасти за счёт кэширования. Хотя, насколько я знаю, большинство компиляторов действуют по другому алгоритму и инстанциируют по-жадному всё что видят. То есть вроде как плюсов получается совсем нет, одни накладные расходы.
здесь вроде как никаких инстанциирований нет. Кэширует ли компилятор значения функции factorial? Как-то очень сомневаюсь. Но в принципе и так неплохо, раз нам удалось сократить количество инстанциирований (операции не из дешёвых).
Вроде выбор напрашивается. Надо предпочитать constexpr функции. Но если смотреть реализации stl, то получается многие идут по первому пути (н-р реализация наибольшего общего делителя _gcd из std::ratio для gcc и msvc). Значит есть какие-то проблемы с constexpr подходом. Так вот какие?
Re: Предпочтительный способ вычислений во времени компиляции
Здравствуйте, sergii.p, Вы писали:
SP>собственно в C++, есть два способа делать одно и то же. SP>Например посчитать факториал можно с помощью инстанциирования шаблонов:
SP>Другой способ в constexpr функциях
Есть еще третий способ вычисления до компиляции
Re: Предпочтительный способ вычислений во времени компиляции
SP>Вроде выбор напрашивается. Надо предпочитать constexpr функции. Но если смотреть реализации stl, то получается многие идут по первому пути (н-р реализация наибольшего общего делителя _gcd из std::ratio для gcc и msvc). Значит есть какие-то проблемы с constexpr подходом. Так вот какие?
constexpr не было до C++11, в подходах инерция и нет причины менять сейчас.
The God is real, unless declared integer.
Re: Предпочтительный способ вычислений во времени компиляции
Здравствуйте, sergii.p, Вы писали:
SP>собственно в C++, есть два способа делать одно и то же. SP> SP>Вроде выбор напрашивается. Надо предпочитать constexpr функции. Но если смотреть реализации stl, то получается многие идут по первому пути (н-р реализация наибольшего общего делителя _gcd из std::ratio для gcc и msvc). Значит есть какие-то проблемы с constexpr подходом. Так вот какие?
Ничего не имею против функций, но вариант реализации на шаблонах структур тоже имеет право на жизнь, я считаю. Благо необходимось в шаблонной рекусии отпала во многих случаях, после появления variadic templates и fold expressions:
Здравствуйте, rg45, Вы писали:
R>Ничего не имею против функций, но вариант реализации на шаблонах структур тоже имеет право на жизнь, я считаю.
почему? Какие ваши аргументы?
R>Благо необходимось в шаблонной рекусии отпала во многих случаях, после появления variadic templates и fold expressions:
ну вот я приводил пример реализации вычисления НОД в stl. Выражения свёртки тут не помогут. К тому же это С++17. Поиграться конечно можно. Но ни одного реального проекта в своём кругу знакомых пока не знаю.
Re[3]: Предпочтительный способ вычислений во времени компиля
Здравствуйте, sergii.p, Вы писали:
R>>Ничего не имею против функций, но вариант реализации на шаблонах структур тоже имеет право на жизнь, я считаю.
SP>почему? Какие ваши аргументы?
Исходя из презумпции права на жизнь. Это право существует до тех пор, пока не обосновано обратное. В данном конкретном примере
нет последовательного инстанцирования шаблонов, о котором ты говоришь выше. Сложность реализации соизмерима с "функциональным" вариантом. Так почему, спрашивается, нужно отказать этому варианту в праве на жизнь?
SP>ну вот я приводил пример реализации вычисления НОД в stl. Выражения свёртки тут не помогут. К тому же это С++17. Поиграться конечно можно. Но ни одного реального проекта в своём кругу знакомых пока не знаю.
Возможно, это тот случай, когда использование шаблонов классов менее оправдано, чем использование constexpr функций. В то же время, найдутся и другие задачи, которые наоборот, будет более рационально решать при помощи шаблонов классов. Например, такие задачи, при прешении которых востребованы частичная специализация и активное использование SFINAE. Конечно, большинство задач можно решить и тем, и другим способом — благодаря тому, что отсутствие частичной специализации для шаблонов функций почти всегда можно компенсировать возможностью перегузок. Просто на шаблонах классов такие задачи может оказаться решать банально проще и нагляднее.
Я бы сказал так, когда мы стакливаемся с необходимостью шаблонной рекурсии, при этом существует равноценный вариант решения на constexpr функциях, то, наверное, стоит отдавать предпочтение ему. А вообще, на мой взгляд, поиски УНВЕРСАЛЬНОГО предпочтительного решения несколько наивны.
--
Не можешь достичь желаемого — пожелай достигнутого.