Tag Archives: C++

Experimental code for simulating Reflection in C++

Motivation for looking at Reflection in C++

At work, we have two frameworks for developing new components – one in C++ and the other in F#. The F# framework is newer and benefits from the insight of previous years working with the C++ framework. In particular, the new F# framework only requires developers to implement a reduced, strongly typed interface in F# by defining a few types (e.g. records) and associated functions between them. This reduced interface is inflated into a full model by the framework, making heavy use of .NET Reflection.

The F# framework has delivered productivity improvements (development time down to a third compared to the previous C++ framework). But the philosophical question remains – how much of that is due to the new architecture developed with the benefit of hindsight? And could we replicate that architecture in C++? The main functionality gap comes down to this: in F# you can use .NET Reflection to discover the names and types of fields in F# types such as unions, records and options, but in C++ you can’t.

Requirements

A full implementation of Reflection for C++ would include ability to discover type information, field names, properties and methods, as well as being able to create instances of types and invoke methods.  I’m interested in a small subset of that scope – the ability to discover the names and values of fields in a C++ struct.

Solution

#include "stdafx.h"

#include <iostream>
#include <string>

#include <boost\preprocessor.hpp>
#include <boost\preprocessor\variadic\size.hpp>
#include <boost\type_traits.hpp>

#include <boost\mpl\range_c.hpp>
#include <boost\mpl\for_each.hpp>

#define REMOVE_BRACKETS(...) __VA_ARGS__
#define REMOVE_NEXT(x)
#define STRIP_TYPE(x) REMOVE_NEXT x
#define DECLARE_DATA_MEMBER(x) REMOVE_BRACKETS x
#define TYPE_ONLY(x) x REMOVE_NEXT(

#define REFLECTABLE(...) \
  static const int number_of_fields = BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \
  friend struct Reflector; \
  \
  template<int N, class Parent = void> \
  struct FieldData {}; \
  \
  BOOST_PP_SEQ_FOR_EACH_I(REFLECT_EACH, data, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

#define REFLECT_EACH(r, data, i, x) \
  DECLARE_DATA_MEMBER(x); \
  template<class Parent> \
  struct FieldData<i, Parent> \
  { \
    Parent & parent; \
    FieldData(Parent& p) : parent(p) {} \
    \
    TYPE_ONLY x ) & get() const \
    { \
      return parent.STRIP_TYPE(x); \
    }\
    const char * name() const \
    {\
      return BOOST_PP_STRINGIZE(STRIP_TYPE(x)); \
    } \
  }; \

struct Reflector
{
  // Get a FieldData instance for the N'th field in type T
  template<int N, class T>
  static typename T::template FieldData<N, T> getFieldData(T& x)
  {
    return typename T::template FieldData<N, T>(x);
  }

  // Reflector is a friend of T, so has access to the private member T::number_of_fields
  template<class T>
  struct FieldCounter
  {
    static const int count = T::number_of_fields;
  };
};

// FieldDispatcher - calls Visitor::visit for each field in T
template<class T, class Visitor>
struct FieldDispatcher
{
  FieldDispatcher( T& t, Visitor visitor ) :
  t(t),
  visitor(visitor)
  {
  }

  template<class FieldIterator>
  void operator()(FieldIterator)
  {
    auto field = Reflector::getFieldData<FieldIterator::value>(t);
    visitor.visit( field );
  }

  T& t;
  Visitor visitor;
};

template<class T, class Visitor>
void for_each_field(T& t, Visitor visitor)
{
  typedef boost::mpl::range_c<int, 0, Reflector::FieldCounter<T>::count> FieldList;
  FieldDispatcher<T, Visitor> field_dispatcher( t, visitor );

  // For each field in T, dispatch the visitor to that field
  boost::mpl::for_each<FieldList>( field_dispatcher );
}

struct PrintNameValueVisitor
{
  template<class FieldData>
  void visit( FieldData field )
  {
    std::cout << field.name() << "=" << field.get() << std::endl;
  }
};

struct Person
{
  Person(const char *first_name, int age, const char* street, const char* town) :
    first_name(first_name),
    age(age),
    street_name(street),
    town(town)
    {
    }

  REFLECTABLE
  (
    (const char *) first_name,
    (int) age,
    (std::string) street_name,
    (std::string) town
  )
};

int _tmain(int argc, _TCHAR* argv[])
{
  Person p("John", 31, "Electric Avenue", "Harrogate" );
  for_each_field(p, PrintNameValueVisitor());

  return 0;
}

Output

Output

Conclusions

The code above ‘works’ – it satisfies the requirements by providing a way to decorate a struct with metadata that can be used to return the names and values of each field. However, in Visual Studio 2010 and 2012, it produces compiler warnings (due to the macro hackery in TYPE_ONLY) and confuses intellisense (which doesn’t cope with the REFLECTABLE macro). In practical terms, that makes it unsuitable, because the productivity benefits are lost when intellisense and auto-complete stop working.

2 Comments

Filed under C++ Code

C++ pre-processor and decltype references

I’m experimenting with the Boost PP library and found these links useful: C Preprocessor, difference between std::result_of and decltype and name lookup tricks (the latter has a handy trick for declaring return types in a template to workaround name lookup phase issues). The question on StackOverflow that promted me to look at Boost PP was reflection in C++

Leave a comment

Filed under C++

Capture-by-Move for lambdas in C++

Marco Arena looks at how to implement move semantics for lambda captures – useful if you wish to capture a large object without using shared_ptr (perhaps to avoid other parties mutating the object outside the lambda).

John Bandela proposed an alternative approach.

All very interesting, but as the comments suggest, it’s best to introduce an extra parameter to the lambda and use std::bind:

function CreateLambda()
{
  std::vector<Huge> hugeObj;
  // ...preparation of hugeObj...

  auto toReturn = std::bind(
    [](std::vector<Huge>& hugeObj)
    { /*..operate on hugeObj..*/ },
    std::move(hugeObj));

  return toReturn;
}

Leave a comment

Filed under C++

Introduction to Modern C++ Techniques

Excellent tutorial on a selection of Modern C++ techniques by Michael Caisse.

Topics include:
Policy Based Design
SFINAE
Tag Dispatching
Traits
Curious Recurring Template Pattern

This is a two part video series:

and with slides.

Leave a comment

Filed under C++, Video

Visual Studio 2012 fixes many C++11 bugs found in VS 2010

Alex Korban (author of C++ Rocks) has compiled a list of C++ features that work better in VS 2012 than in VS 2010 thanks to 23 bug fixes.

Leave a comment

Filed under C++

std::initializer_list – an even better way to populate a vector

Visual Studio 2012 November CTP does provide us with support for initializer lists, even though standard library containers like vector<T> do not yet implement constructors that accept an initializer list.  However, that doesn’t stop us writing code like this to make populating containers easy:

namespace musingstudio
{
  template<typename Container>
  Container initialize( 
    std::initializer_list<typename Container::value_type> items )
  {
    return Container( items.begin(), items.end() );
  }
}

And call it like this:

auto evens = musingstudio::initialize<vector<int>>({2,4,6,8,10});

I like the way this reads “initialize vector of int( values )” – and it’s pretty efficient too, if your container supports move semantics (which the standard library containers do).

2 Comments

Filed under C++ Code

Variadic Templates – example that simplifies populating a vector

I was hoping that Visual Studio 2012 would allow us to initialise a std::vector; like this, especially with the November CTP:

std::vector<int> items = { 1, 2, 3, 4, 5 };

However, although the November CTP includes support for variadic templates and uniform initialisation, they haven’t yet decorated all standard templates with initializer lists as needed for the above. That tempted me to write a simple variadic template to avoid having to write code like this ever again:

std::vector<int> items;
items.push_back(0);
items.push_back(1);
items.push_back(2);

By writing this:

namespace musingstudio
{
  template<typename T, typename U, typename ...Args>
  void push_back(std::vector<T>& items, U item, Args ...args)
  {
    items.push_back(item);
    push_back( items, args... );
  }

  template<typename T, typename U>
  void push_back(std::vector<T>& items, U item)
  {
    items.push_back(item);
  }
}

We can then write this:

std::vector<int> items;
musingstudio::push_back( items, 0,1,2,3,4,5 );

Obviously, this is less efficient than implementing a constructor that takes initializer lists, but it’s more fun than repeatedly typing push_back the C++98/03 way.

Leave a comment

Filed under C++ Code

Herb Sutter Podcast – “Why C++?” on HanselMinutes

HanselMinutes interviews Herb Sutter on “Why C++?”

The world runs on C and C++. Did you know that? Herb Sutter sits down to convince Scott that he’s not only standing on the shoulders of giants but that those giants all write C++.

Leave a comment

Filed under C++, Podcast

Rule of Zero

Interesting take on the need or otherwise to write move constructors by R. Martinho Fernandes (Flaming Dangerzone) :-

So, we have arrived at the Rule of Zero (which is actually a particular instance of the Single Responsibility Principle):

Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.

Leave a comment

Filed under C++

Stephan Lavavej Video – VS2012 C++ November CTP

Introductory video on the Visual Studio 2012 C++ Compiler November CTP (download the CTP here):

A special episode in which Stephan takes a look at the latest C++11 features that were just added to the Visual C++ compiler:

Variadic templates
Raw string literals
Explicit conversion operators
Default template arguments for function templates
Delegating constructors
Uniform initialization

Click to watch the video

Leave a comment

Filed under C++, Video