Ответ 1
И кроме примера pi, как бы он работал с неконстантными переменные?
В настоящее время создается экземпляр переменных отдельно для типа. то есть вы можете назначить 10 на n<int>
, и это будет отличаться от определения шаблона.
template<typename T>
T n = T(5);
int main()
{
n<int> = 10;
std::cout << n<int> << " "; // 10
std::cout << n<double> << " "; // 5
}
Если объявление const
, оно только для чтения. Если он constexpr
, как и все объявления constexpr
, он не имеет большого значения вне constexpr
(ressions).
Кроме того, мы можем использовать эту функцию, просто обернув переменную в шаблонной структуре или классе, как это смешивается с типом преобразования?
Это было простое предложение. Я не могу понять, как это сильно влияет на преобразования типов. Как я уже сказал, тип переменной - это тип, с которым вы создавали шаблон. т.е. decltype(n<int>)
является int. decltype((double)n<int>)
- двойное и т.д.
Любой пример использования, чтобы понять, как максимально использовать такую функцию и какова его цель?
N3651 дает краткое обоснование.
Увы, существующие правила С++ не позволяют объявление шаблона объявить переменную. Известны обходные пути для этого Проблема:
• использовать constexpr статические элементы данных шаблонов классов
• использовать шаблоны функций constexpr, возвращающие нужные значения
Эти обходные решения известны десятилетиями и хорошо документированы. Стандартные классы, такие как std:: numeric_limits, являются архетипическими Примеры. Хотя эти обходные пути не идеальны, их недостатки были в некоторой степени переносимы, потому что в эпоху С++ 03 только простые, встроенные типы констант пользовались неограниченным прямым и эффективным время компиляции. Все это изменилось с принятием constexpr в С++ 11, что расширяет прямые и эффективные поддержка констант пользовательских типов. Теперь программисты делая константы (типов классов) все более очевидными в программах. Так вырастайте путаница и разочарования, связанные с обходные пути.
...
Основные проблемы со "статическим элементом данных":
• им требуются "повторяющиеся" объявления: один раз внутри класса шаблон, один раз за пределами шаблона класса, чтобы обеспечить "реальный" в том случае, если константы используются нечасто.
• Программисты оба недоумевают и путаются необходимостью предоставления в два раза того же декларация. Напротив, "обычные" константные объявления не нужны дублировать декларации.
...
Известные примеры в этой категории, вероятно, являются статическими элементами функции numeric_limits или функции, такие как
boost::constants::pi<T>()
и т.д. Шаблоны функций Constexpr не страдают от "повторяющихся заявлений" о том, что статические члены данных иметь; кроме того, они обеспечивают функциональную абстракцию. Однако они заставляют программиста заранее выбирать на сайте определения, как константы должны быть доставлены: либо по ссылке const, либо по простой неориентированный тип. Если доставляется константой const, то константы должны систематически выделяться в статическом хранилище; если не ссылочным типом, то константы нуждаются в копировании. Копирование не является проблема для встроенных типов, но это showstopper для пользовательских типы со смысловой семантикой, которые arent просто обертки вокруг крошечных встроенные типы (например, матрица или целое число, или bigfloat и т.д.). контраст, "обычные" константы (expr) не страдают от этого проблема. Предоставлено простое определение, и решение нужны ли константы для компоновки только в хранилище зависит от использования, а не от определения.