BOOST Code Reading - A Simple Metaprogramming Trick

Sometimes, we need a metafunction to have this effect which is that when we pass a type with certain series of tag, if the type contain the tag, then return the tag, otherwise just return the void.

This might be a simple metafunction, but when I encounter this trick at the very first time, it confused me a lot. The code snippit as follows:

#include <bits/stdc++.h>
#include <boost/graph/properties.hpp>
#include <boost/graph/adjacency_list.hpp>

using namespace boost;

template <typename A> struct return_void {typedef void type;};

template <typename Graph, typename Enable = void>
struct graph_tag_or_void {
    typedef void type;
};

template <typename Graph>
struct graph_tag_or_void<Graph, typename return_void<typename Graph::graph_tag>::type> {
    typedef typename Graph::graph_tag type;
};

typedef adjacency_list<vecS, vecS, directedS> Graph;

void tst() {
    std::cout << std::is_same<return_void<Graph::graph_tag>::type, void>::value << std::endl;
    std::cout << std::is_same<Graph::graph_tag, graph_tag_or_void<Graph>::type>::value << std::endl;
}

int main() {
    tst();
    return 0;
}

As you can see, if a type have graph_tag, then graph_tag_or_void<Graph>::type will return Graph::graph_type and voidon the contrary. Here I will explain why that happened.

Firstly we have a metafunctionreturn_void which always return void from::type. This function may seemed useless, but in the metafunction graph_tag_or_void, this function can help us to detect whether the type have graph_tag.

If it does have graph_tag, then the second specialization will be called. On the other hand, it will just call the first one, which always return void.