17.2 Enumeration Values versus Static Constants

Ru-Brd

In old C++ compilers, enumeration values were the only available possibility to have "true constants" (so-called constant-expressions ) inside class declarations. However, this has changed during the standardization of C++, which introduced the concept of in-class static constant initializers. A brief example illustrates the construct:

 struct TrueConstants {      enum { Three = 3 };      static int const Four = 4;  }; 

In this example, Four is a "true constant" ”just as is Three .

With this, our Pow3 metaprogram may also look as follows :

  // meta/pow3b.hpp  #ifndef POW3_HPP  #define POW3_HPP  // primary template to compute  3  to the  N  th  template<int N>  class Pow3 {    public:      static int const result = 3 * Pow3<N-1>::result;  };  // full specialization to end the recursion  template<>  class Pow3<0> {    public:      static int const result = 1;  };  #endif  // POW3_HPP  

The only difference is the use of static constant members instead of enumeration values. However, there is a drawback with this version: Static constant members are lvalues. So, if you have a declaration such as

 void foo(int const&); 

and you pass it the result of a metaprogram

 foo(Pow3<7>::result); 

a compiler must pass the address of Pow3<7>::result , which forces the compiler to instantiate and allocate the definition for the static member. As a result, the computation is no longer limited to a pure "compile-time" effect.

Enumeration values aren't lvalues (that is, they don't have an address). So, when you pass them "by reference," no static memory is used. It's almost exactly as if you passed the computed value as a literal. These considerations motivate us to use enumeration values in all metaprograms throughout this book.

Ru-Brd


C++ Templates
C++ Templates: The Complete Guide
ISBN: 0201734842
EAN: 2147483647
Year: 2002
Pages: 185

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net