C++ Template metaprogramming

J

jacob navia

Hi

I am reading "C++ Template Metaprogramming" by Abrahams and Gurtovoy.

It is quite difficult to follow, specially because the 'practical'
applications shown are very abstract: parsers, and other stuff.

In this context I have some questions for this group:

o Are you doing template metaprogramming?
o If yes, what applications are you targeting?
o If no why?

Thanks in advance. My objective is to see the end product of
all this stuff, to help me better understand it.
 
I

Ian Collins

jacob said:
Hi

I am reading "C++ Template Metaprogramming" by Abrahams and Gurtovoy.

Welcome to the dark side!

That book certainly isn't what I'd call light reading, but it does
introduce some valuable techniques.
It is quite difficult to follow, specially because the 'practical'
applications shown are very abstract: parsers, and other stuff.

I thought you were a compiler writer?
In this context I have some questions for this group:

o Are you doing template metaprogramming?
Yes.

o If yes, what applications are you targeting?

So far, fairly simple cases where run time recursion solution would be
use, for example byte order reversal and for typelists (Alexandrescu
"Modern C++ Design").
Thanks in advance. My objective is to see the end product of
all this stuff, to help me better understand it.

Template Metaprogramming is still a technique in its infancy and not yet
widely used, probably because (as you have discovered) it takes a log of
getting used to.
 
L

Laurent Deniau

Hi

I am reading "C++ Template Metaprogramming" by  Abrahams and Gurtovoy.

It is quite difficult to follow, specially because the 'practical'
applications shown are very abstract: parsers, and other stuff.

In this context I have some questions for this group:

o Are you doing template metaprogramming?

I did some from 1997-99
o If yes, what applications are you targeting?

scientific computation (project Scientific Library in C++ aka SL++)
The project is unmaintained since then but is still the first hit with
google for SL++ ;-)
o If no why?

because of lack of time and change of technology ;-)
Thanks in advance. My objective is to see the end product of
all this stuff, to help me better understand it.

TMP is useful for adding syntactic sugar to you code/libraries (DSL)
and/or optimize your code by generating more efficient constructions
(e.g. avoiding to build temporaries by flattening/fusing expressions).
Both are generally used in parallel. If you are not interested by
either of these aspects, it's of little use. But do not underestimate
the usefulness of syntactic sugar (e.g. through operator overloading).
The drawbacks are longer compilation time and code slightly more
difficult to understand (and debug) if you are not trained to template
specialization and template expression. Looking at a library which
provides support for generic TMP (like Boost MPL) is a good starting
point.

a+, ld.
 
N

Noah Roberts

jacob said:
o Are you doing template metaprogramming?
Yes

o If yes, what applications are you targeting?

Extending the type system to encompass compile time dimensional analysis.

A generic but compile time constructed record structure for building
field editors, field IO, etc, that's type safe and extensible.

I more regularly use some of the techniques learned in that book in
generic programming terms.
 
N

Noah Roberts

Jeff said:
and recently used TMP to enable some simple
aspect-oriented programming (which raw C++ doesn't support very well).

I'd be interested in how.
 
N

Noah Roberts

Jeff said:
Here's a complete, but over-simplified, sample program. I apologize for
the length of the post; the syntax is verbose, and I included a lot of
comments.

Thanks! I'll give this some study.
 
M

ma740988

Extending the type system to encompass compile time dimensional analysis.
Interesting!

A generic but compile time constructed record structure for building
field editors, field IO, etc, that's type safe and extensible.

Could you show a synopsis on how you're doing this?
 
N

Noah Roberts

ma740988 said:
Interesting!

Not that much anymore. Has been pretty much solved in the boost library.
Could you show a synopsis on how you're doing this?

The following is some scratch I put together for a presentation at a
local college. It's functional and almost complete. It doesn't address
problems you'll have with namespaces and using the MSVC method in g++ or
others.

#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/for_each.hpp>

//#define MSVC // uncomment if you have visual studio. Also fine in g++

#define DECLARE_FIELD(NAME,TYPE) \
struct NAME \
{ \
typedef TYPE type; \
static char const* name() { return #NAME ; } \
}


template < typename CONT, typename FIELD, typename TYPE, TYPE CONT::*addr >
struct record_field_desc
{
typedef CONT member_of;
typedef FIELD field;
typedef TYPE type;

static TYPE get(CONT const& cont) { return cont.*addr; }
static void set(CONT & cont, TYPE const& value) { cont.*addr = value; }
};

template < typename REC >
struct meta
{
typedef typename REC::meta type;
};
#ifndef MSVC

#define BEGIN_META(CONT) \
struct meta { typedef boost::mpl::vector<CONT

#define ADD_FIELD(CONT, FIELD, ADDR) \
, record_field_desc<CONT, FIELD, FIELD::type, ADDR>

#define END_META() \
> fields; \
typedef boost::mpl::next<boost::mpl::begin<fields>::type>::type begin; \
typedef boost::mpl::end<fields>::type end; \
};

#else

#define BEGIN_META(CONT) \
struct CONT_meta \
{ \
typedef boost::mpl::vector<CONT

#define ADD_FIELD(CONT, FIELD, ADDR) \
, record_field_desc<CONT, FIELD, FIELD::type, ADDR>

#define END_META(CONT) \
> fields; \
typedef boost::mpl::next< boost::mpl::begin<fields>::type >::type begin; \
typedef boost::mpl::end<fields>::type end; \
}; \
\
template <> struct meta<CONT> { typedef CONT_meta type; };

#endif

DECLARE_FIELD(test1, int);
DECLARE_FIELD(test2, double);
DECLARE_FIELD(test3, long);

struct test_record
{
int x;
double y;

#ifndef MSVC
BEGIN_META(test_record)
ADD_FIELD(test_record, test1, &test_record::x)
ADD_FIELD(test_record, test2, &test_record::y)
//ADD_FIELD(test_record, test3, &test_record::y) // uncomment to
see error
END_META()
#endif
};

#ifdef MSVC
BEGIN_META(test_record)
ADD_FIELD(test_record, test1, &test_record::x)
ADD_FIELD(test_record, test2, &test_record::y)
END_META(test_record)
#endif



// UTILITY STUFF
template < typename T >
struct type_desc
{
static char const* desc() { return typeid(T).name(); }
};
template <>
struct type_desc<int> { static char const* desc() { return "integer"; } };
template <>
struct type_desc<double> { static char const* desc() { return "real
number"; } };

template < typename REC >
struct record_reader
{
struct field_reader
{
REC & rec;
field_reader(REC & r) : rec(r) {}

template < typename FIELD_DESC >
void operator() (FIELD_DESC const&) const
{
typedef typename FIELD_DESC::type type;
std::cout << "Enter a " << type_desc<type>::desc() << " for " <<
FIELD_DESC::field::name() << ": ";

type t;
std::cin >> t;

FIELD_DESC::set(rec, t);
}
};

static REC read_record()
{
REC rec;
boost::mpl::for_each< typename meta<REC>::type >(field_reader(rec));
return rec;
}
};

template < typename REC >
struct record_writer
{
struct field_writer
{
REC const& rec;
field_writer(REC const& r) : rec(r) {}

template < typename FIELD_DESC >
void operator() (FIELD_DESC const&) const
{
std::cout << "Value for "
<< FIELD_DESC::field::name()
<< " is: " << FIELD_DESC::get(rec) << std::endl;
}
};

static void write_record(REC const& r)
{
boost::mpl::for_each< typename meta<REC>::type >(field_writer(r));
}
};

int main()
{
test_record rec = {};
record_writer<test_record>::write_record(rec);

rec = record_reader<test_record>::read_record();

record_writer<test_record>::write_record(rec);
}
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top