Reputation: 9122
C++14 introduced variable templates (Variable templates).
template<class T>
constexpr T pi = T(3.1415926535897932385); // variable template
template<class T>
T circular_area(T r) // function template
{
return pi<T> * r * r; // pi<T> is a variable template instantiation
}
What is the overhead of using this, both in terms of the binary memory footprint and speed at runtime?
Upvotes: 1
Views: 507
Reputation: 30624
Given;
template<class T>
constexpr T pi = T(3.1415926535897932385); // when T is double
// and
constexpr double pi = 3.1415926535897932385;
There is no runtime difference, they are both compile time constants. Templates are a compile time thing - as such, when comparing like with like (i.e. constexpr double pi
vs. constexpr T pi
) it would end up being the same - this is expected.
What does make a difference from the OP code is how it is used.
template<class T>
T circular_area_t(T r) // function template
{
return pi<T> * r * r; // pi<T> is a variable template instantiation
}
// and
constexpr double circular_area_1(double r)
{
return pi<double> * r * r;
}
double circular_area_2(double r)
{
return pi<double> * r * r;
}
Given the constexpr
function circular_area_1
and the template function circular_area_t
, both of these result in compile time calculations, hence literals in the binary, of the result. The non-constexpr
function circular_area_2
is compiled as a normal function and is executed at runtime to determine the result. This makes a difference at runtime. See here for a code listing.
Upvotes: 0
Reputation: 129524
I'd definitely report this as a bug to the compiler maker if there is ANY difference between:
template<class T>
constexpr T pi = T(3.1415926535897932385); // variable template
template<class T>
T circular_area(T r) // function template
{
return pi<T> * r * r; // pi<T> is a variable template instantiation
}
and
constexpr double pi = 3.1415926535897932385;
double circular_area(double r)
{
return pi * r * r;
}
And the same if you replace double
with float
.
In general, constexpr
should evaluate to the relevant constant directly in the compiled code. If it can't do that, then the compiler should give an error (because it's not a true constexpr
).
Upvotes: 5