template metaprogramming syntax

  • Thread starter nooneinparticular314159
  • Start date
N

nooneinparticular314159

I'm trying to understand template metaprogramming syntax. It's been
years since I've touched C++, so this may actually be a C++ syntax
issue (although it seems that the language has changed somewhat.)

The following example comes from http://www.codeproject.com/KB/cpp/crc_meta.aspx

template< int i >
class FACTOR{
public:
enum {RESULT = i * FACTOR<I-1>::RESULT};
};

class FACTOR< 1 >{
public:
enum {RESULT = 1};
};

In the line enum {RESULT = i * FACTOR<I-1>::RESULT};, what is the
purpose of the ::RESULT? As I understand it, this should be calling a
method called RESULT, but I don't think this is what is actually
happening.

Also, why is everything done on one line with enumerated types in
every template example I see? Why are enumerated types used instead
of normal loops? Is this because the loops must be evaluated as
constants at compile time?

Thanks!
 
S

sonison.james

I'm trying to understand template metaprogramming syntax.  It's been
In the line enum {RESULT = i * FACTOR<I-1>::RESULT};, what is the
purpose of the ::RESULT?  As I understand it, this should be calling a
method called RESULT, but I don't think this is what is actually
happening.

There are some typos in the code provided. Here's the same code with a
sample usage which would probably make the intention clear

#include <iostream>
using namespace std;

template< int i >
class FACTOR{
public:
enum {RESULT = i * FACTOR<i-1>::RESULT};

};

template<>
class FACTOR< 1 >{
public:
enum {RESULT = 1};

};

int main()
{
cout << "3!=" << FACTOR< 3 >::RESULT << endl;
}

In this sample we can let the compiler evaluate for us the value of a
factorial of a number at compile time. Since at compile time the
compiler does not have access to run time entities like objects or
invoke a function calls meta programming is in some sense restricted
to manipulate only entities available at compile time like types
including enums.

In case you haven't already checked out boost MPL, it has some good
reads at http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/index.html

Thanks and regards
Sonison James
 
M

Maxim Yegorushkin

I'm trying to understand template metaprogramming syntax.  It's been
years since I've touched C++, so this may actually be a C++ syntax
issue (although it seems that the language has changed somewhat.)

The syntax did not change.
The following example comes fromhttp://www.codeproject.com/KB/cpp/crc_meta.aspx

template< int i >
class FACTOR{
  public:
      enum {RESULT = i * FACTOR<I-1>::RESULT};

};

class FACTOR< 1 >{

this should be:

template said:
  public:
      enum {RESULT = 1};

};

In the line enum {RESULT = i * FACTOR<I-1>::RESULT};, what is the
purpose of the ::RESULT?

:: is the scope resolution operator. FACTOR<I-1>::RESULT says lookup
member RESULT in FACTOR said:
As I understand it, this should be calling a
method called RESULT, but I don't think this is what is actually
happening.

Everything here happens in compile time, so that no call can be made.
As RESULT member is essentially an integer whose value is known at
compile time FACTOR said:
Also, why is everything done on one line with enumerated types in
every template example I see?

It can be static constant integers as well, however, some old
compilers could not handle it. Enums is a bit more portable. I.e. in
this context:

enum {RESULT = 1};

is the same as:

static int const RESULT = 1;
Why are enumerated types used instead of normal loops?  
Is this because the loops must be evaluated as
constants at compile time?

Compile time loops can only be expressed as recursion, because you can
not change variables at compile time.

The following may help you get started with template metaprogramming:
http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/tutorial/resources.html
 
N

nooneinparticular314159

Thanks! So to see if I understand this correctly, the line:
enum {RESULT = i * FACTOR<I-1>::RESULT};

means that I am going to perform a computation where I multiply the
result of evaluating the class FACTOR on the value I-1, and I'm going
to store that result in RESULT, which the compiler stores somewhere as
a constant. Then with the RESULT after the ::, I'm directing the
compiler to look up the value contained in RESULT, and that is the
value that is actually being returned from the evaluation of the
entire line. Is that correct?

Thanks!
 
H

Hendrik Schober

Thanks! So to see if I understand this correctly, the line:
enum {RESULT = i * FACTOR<I-1>::RESULT};

means that I am going to perform a computation where I multiply the
result of evaluating the class FACTOR on the value I-1, and I'm going
to store that result in RESULT, which the compiler stores somewhere as
a constant. Then with the RESULT after the ::, I'm directing the
compiler to look up the value contained in RESULT, and that is the
value that is actually being returned from the evaluation of the
entire line. Is that correct?

AFAIU, no.
I have added some parentheses:
enum { RESULT = i * (FACTOR<I-1>::RESULT) };
The 'FACTOR<I-1>::RESULT' is a compile-time constant
of (I-1)! which is used to calculate the compile-time
constant 'RESULT'.
Does this help?

Schobi
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top