DevShark
DevShark

Reputation: 9122

Overhead of variable template

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

Answers (2)

Niall
Niall

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

Mats Petersson
Mats Petersson

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

Related Questions