Originally posted by: zyxsh
The variable template, which comes from N3651, is one of the major proposals in Standard C++14. The main purpose of the variable template is to simplify definitions and uses of parameterized constants. [1][2]
Rules before C++14 do not allow declaring a variable using a template declaration. There are workarounds for this problem before C++14, but they are either redundant or complicated.
The first workaround is constexpr static data members of class templates as shown in Code 1. However, duplicate declarations are required: one inside the class template and another one outside the class template, which provides the real definition in case the constant is ODR (One Definition Rule) used.
The second workaround is constexpr function templates as shown in Code 2, which returns the desired values.
CODE 1
#include<stdio.h>
template <typename T>
struct PI {
static constexpr T pi = T(3.1415926535897932385);
};
template <typename T>
constexpr T PI<T>::pi;
int main()
{
printf("%d\n", PI<int>::pi);
printf("%lf\n", PI<double>::pi);
return 0;
}
|
CODE 2
#include<stdio.h>
template <typename T>
T PI()
{
constexpr T pi = T(3.1415926535897932385);
return pi;
}
int main()
{
printf("%d\n", PI<int>());
printf("%lf\n", PI<double>());
return 0;
}
|
Now with variable templates of C++14, manipulation of constant values with various types can be significantly simplifiedas demonstrated in the most frequently used example -- PI<T>. PI is declared as a variable template, and given a constant value 3.1415926535897932385 with type conversion. If the use of template is initialized with PI<int>, PI is initialized with a type conversion of 3.1415926535897932385. Code 3 is an example of using the variable template. The example is compiled with Clang 3.6.1, and executed on an OpenPower system.
CODE 3
#include <stdio.h>
template<typename T>
constexpr T PI = T(3.1415926535897932385);
template<typename T>
T area (T r) {
return PI<T> * r * r;
}
int main()
{
printf("PI: %d, area: %d\n", PI<int>, area(2));
printf("PI: %lf, area: %lf\n", PI<double>, area(2.0));
return 0;
}
|
OUTPUT
PI: 3, area: 12
PI: 3.141593, area: 12.566371
|
At last, let’s have a look at what will happen when applying templates to non-constant variables. In Code 4, for example, when assigning a different value, 0.618, to PI<float>, PI<double> is not changed. It is not difficult to understand because the variable follows the rules of templates that initialize the instance for each use.
CODE 4
#include <stdio.h>
template<typename T>
T Value = T(3.1415926535897932385);
int main()
{
Value<float> = 0.6180339887498948482;
printf("%f\n", Value<float>);
printf("%lf\n", Value<double>);
return 0;
}
|
OUTPUT
0.618034
3.141593
|
REFERENCE
[1] Gabriel Dos Reis, N3651 Variable Templates, Revision 1, C++14 proposal, 2013.
[2] Chandra Shekhar Kumar, C++14 FAQs,2015.
English Editor: Jia Lei Ma (Yvonne). Many thanks for Yvonne’s help !