Reply to comment

Boost Preprocessor Metaprogramming and Intro to Templates Revisited

Say you come up with a clever idea for initializing standard container types (blatantly stolen from the C++0x Initializer List concept). It might looks something like the implementation below:

#include <vector>
 
using namespace std;
 
template<template<typename DT> class container, typename DT>
container<DT> initializer(const DT &d)
{
  container<DT> t;
  t.insert(t.end(), d);
  return t;
}
 
int main(int, char *[])
{
  vector<int> v = initializer<vector>(5);
}

But that only works for 1 parameter! Let's add a second one:

#include <vector>
 
using namespace std;
 
template<template<typename DT> class container, typename DT>
container<DT> initializer(const DT &d)
{
  container<DT> t;
  t.insert(t.end(), d);
  return t;
}
 
template<template<typename DT> class container, typename DT>
container<DT> initializer(const DT &d, const DT &d2)
{
  container<DT> t;
  t.insert(t.end(), d);
  t.insert(t.end(), d2);
  return t;
}
 
 
int main(int, char *[])
{
  vector<int> v = initializer<vector>(5, 10);
}

OK, now we have up to two parameters supported. This works... kind of. But it gets tedious VERY quickly and is prone to all kinds of code duplication problems. Using the boost preprocessing library, we can quickly and easily make this code work for 1 to 255 parameters.

#include <boost/preprocessor.hpp>
 
#define rep(z, n, text) t.insert(t.end(), d ## n);
 
#ifndef BOOST_PP_IS_ITERATING
# ifndef CONTAINER_INITIALIZER_HPP
# define CONTAINER_INITIALIZER_HPP
 
#define BOOST_PP_ITERATION_LIMITS ( 1, BOOST_PP_LIMIT_ITERATION)
 
#define BOOST_PP_FILENAME_1 "container_initializer.hpp"
#include BOOST_PP_ITERATE()
# endif // FUSION_MAKE_TUPLE_HPP
#else
# define n BOOST_PP_ITERATION()
 
template<template<typename DataType> class Container, typename DataType>
Container<DataType> initializer(
    BOOST_PP_ENUM_PARAMS(n, const DataType &d))
{
    Container<DataType> t;
    BOOST_PP_REPEAT(n, rep, ~)
    return t;
}
 
#endif

I find this to be a much more practical example than what I was showing in my previous post on this topic.

Now, on to the intro to templates. Templates provide a very flexible way of writing generic code. As my test case for the above container initializer, I have written a simple template function that will output a container to standard out. Here is the complete example:

#include "container_initializer.hpp"
 
#include <vector>
#include <list>
#include <string>
#include <set>
#include <iostream>
 
template<typename OutItr>
void print_container(OutItr begin, OutItr end)
{
  while (begin != end) {
    std::cout << *(begin++) << " ";
  }
 
  std::cout << std::endl;
}
 
int main()
{
 
  std::vector<int> v = initializer<std::vector>(5, 16, 43, 27, 192);
  std::list<std::string> l = initializer<std::list, std::string>("hi", "there", "world");
  std::set<std::string> s = initializer<std::set, std::string>("hi","hi","there","world","world");
 
 
  print_container(v.begin(), v.end());
  print_container(l.begin(), l.end());
  print_container(s.begin(), s.end());
}

Any questions?

The first one I can think of, is, what is there one template parameter in the first example (initializer<std::vector>(5, 16, 43, 27, 192)), but two in the second (initializer<std::list, std::string>("hi", "there", "world"))? This is because the compiler was trying to create a std::list of const char *, instead of string. I needed to specify the second type when using strings so that the compiler would apply the conversion to string for me.

Reply

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • Lines and paragraphs break automatically.
  • You may post PHP code. You should include <?php ?> tags.
  • Web page addresses and e-mail addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]". PHP source code can also be enclosed in <?php ... ?> or <% ... %>.
  • Images can be added to this post.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.