I wanted to calculate e
value at compile–time (don't worry, not a homework), yet something went wrong.
template<size_t limit = 3, class result = std::ratio<0, 1>, size_t factorial = 1, size_t count = 1>
constexpr double e_impl() {
if constexpr(limit == 0) {
return static_cast<double>(result{}.num) / result{}.den;
}
return e_impl<limit - 1, std::ratio_add<result, std::ratio<1, factorial>>, factorial * count, count + 1>();
}
While calculated values are correct, compiler throws an error about overflow in template. It seems like limit
variable goes out of range (below 0
), but it shouldn't happen as the 0
–case is being handled by the if constexpr(…)
statement.
So the question is, am I wrong and that behavior should be expected, or is it a compiler bug? Compiled with GCC 7.1.0.
A form template is a single file that contains multiple supporting files, such as files that define how controls on the form template should appear, files for graphics that appear on the form template, and programming files that enable custom behaviors in the form template.
Open the presentation that you want to save as a template. On the File tab, click Save as Template. In the Save As box, type the name that you want to use for the new template. (Optional) In the Where box, choose a location where the template will be saved.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.
To avoid the error, put the second return explicitly into the else branch:
template<size_t limit = 3, class result = std::ratio<0, 1>, size_t factorial = 1, size_t count = 1>
constexpr double e_impl() {
if constexpr(limit == 0) {
return static_cast<double>(result{}.num) / result{}.den;
}
else
{
return e_impl<limit - 1, std::ratio_add<result, std::ratio<1, factorial>>, factorial * count, count + 1>();
}
}
https://godbolt.org/g/PdV7m7
Rational:
During an instantiation of the enclosing function template or generic lambda, if the converted condition is true and the statement includes a constexpr else substatement, that substatement is not instantiated.
http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0128r1.html
It says nothing about an unconstrained else block, or a block which is not supposed to run, so it gets instantiated, throwing the error. (Note: also fails on clang)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With