1

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?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
DevShark
  • 8,558
  • 9
  • 32
  • 56
  • 1
    Like other templates, it will create a separate object for each instantiation (different type) in memory. Effects on runtime may only come from accessing that memory, but are negligible (if you had thousands of these globals that wouldn't fit in cache but frequently used). – ftynse Feb 29 '16 at 08:40

2 Answers2

5

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).

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

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.

Niall
  • 30,036
  • 10
  • 99
  • 142