Search code examples
templatescompiler-constructionc++14programming-languagesmetaprogramming

What is mean by Metafunctions & Metaclasses in Programming Languages?


I have come across these terms many times during compile time c++ computation. I have searched through the web, the resources I found where "expert level" stuffs I can't able to understand it. Could please help to understand these terms ? I'm looking for beginner-level good explanation. Thanks a lot for your kind help! Pree


Solution

  • Metafunctions

    A metafunction in C++ is a way of expressing a compile-time computation using template metaprogramming -- using template instantiation and type deduction to generate results at compile time.

    Fundamentally, a metafunction is a class template with constexpr members (for metafunctions returning values) or typedefs (for metafunctions returning types). The technique can be illustrated by the metafunction is_same which checks if two type parameters are the same. A possible implementation (from cppreference.com) is

    template<class T, class U>
    struct is_same : std::false_type {};
    
    template<class T>
    struct is_same<T, T> : std::true_type {};
    

    where std::true_type is a helper metafunction that has a member constexpr bool value = true (and false for false_type).

    A metafunction is called by instantiating the template and reading the member containing the result, for instance the expression

    is_same<int,int32_t>::value
    

    which will evaluate to the boolean value true if int is 32 bits, and false otherwise.

    Another example, from type_traits is std::is_floating_point, which checks if a type is a floating point type. It can be called as

    is_floating_point<int>::value
    

    The standard library (mostly) has the convention that metafunctions returning values have the member value, and metafunctions returning types have the type alias type.

    An example of a type-returning metafunction is std::iterator_traits which is used to get information about iterators. For intance, given an iterator type Iter, one can get the value type (i.e., the type returned by dereferencing the iterator) with

    iterator_traits<Iter>::value_type
    

    and the iterator category (e.i., ForwardIterator, RandomAccessIterator, etc.) with

    iterator_traits<Iter>::iterator_category
    

    An example of compile-time computation is a metafunction that computes the factorial:

    template <unsigned int N>
    struct Fac{
        static constexpr unsigned int value = N * Fac<N-1>::value; 
    };
    
    template <>
    struct Fac<0>{
        static constexpr unsigned int value = 1;
    };
    

    Again, this metafunction is called as Fac<5>::value

    Metaclasses

    Metaclasses is a proposed addition to C++ to allow expressing constraints on a (kind of) class in code instead of just using conventions and documentation.

    For instance, an "interface" is often used to describe a class that has

    1. only pure virtual public function
    2. a virtual destructor

    With a metaclass interface, that could be written

    interface Example {
        void Foo();
        int  Bar(int);
    }
    

    which would then be instantiated by the compiler to the class

     class Example {
     public:
         virtual void Foo() =0;
         virtual int Bar(int) =0;
         virtual ~Foo() =default;
     }
    

    A good summary of the metaclass proposal can be found at this fluentc++ blog post. A comprehensive source is Herb Sutter's blog post