Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template metaprogramming evaluation

So I have a template class that I would like to accept an std::map where the data type is either a raw pointer or an std::unique_ptr. Then in this class I would like to get the type of the underlying pointer:

typedef typename boost::mpl::if_<
    boost::is_pointer<typename Container::mapped_type>,
    typename Container::mapped_type,
    typename Container::mapped_type::element_type*
>::type data_type

However I get the following error when instantiating the class using a map with a raw pointer type:

error: 'std::map<int, ValueType*>::mapped_type {aka ValueType*}' is not a class, struct, or union type

It seems to me like it is evaluating typename Container::mapped_type::element_type* on the raw pointer, I thought that with template metaprogramming it would not evaluate that when the if_ succeeded. Should I be going about this a different way?

like image 413
grivescorbett Avatar asked May 24 '12 23:05

grivescorbett


People also ask

What is the point of template metaprogramming?

Template metaprogramming is a programming technique that uses templates as blueprints for the compiler to generate code and help developers avoid writing repetitive code.

Which language is best for metaprogramming?

Lisp is probably the quintessential language with metaprogramming facilities, both because of its historical precedence and because of the simplicity and power of its metaprogramming.

What is a metaprogramming language?

Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data. This means that a program can be designed to read, generate, analyze, or transform other programs, and even modify itself while running.

Are generics metaprogramming?

Generics are used for metaprogramming in Ada. They are useful for abstract algorithms that share common properties with each other.


1 Answers

You need a lazy if – try boost::mpl::eval_if instead of boost::mpl::if_:

#include <boost/type_traits/is_pointer.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>

template<typename T>
struct extract_element_type
{
    typedef typename T::element_type* type;
};

template<typename Container>
struct foo
{
    typedef typename boost::mpl::eval_if<
        boost::is_pointer<typename Container::mapped_type>,
        boost::mpl::identity<typename Container::mapped_type>,
        extract_element_type<typename Container::mapped_type>
    >::type data_type;
};

I.e., when in doubt, add an extra layer of indirection.

like image 71
ildjarn Avatar answered Sep 21 '22 01:09

ildjarn