Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practical C++ Metaprogramming

I just read the book "Practical C++ Metaprogramming" and it has the following example that I cannot compile. Can you help sort this out for me.

template <typename F>
struct make_tuple_of_params;

template <typename Ret, typename... Args>
struct make_tuple_of_params<Ret (Args...)>
{
   using type = std::tuple<Args...>;
};

template <typename F>
using make_tuple_of_params_t = typename make_tuple_of_params<F>::type;

template<typename F>
void some_magic_function(F callable)
{
   make_tuple_of_params_t<F> tuple;
   /*
    ... do something with arguments in tuple...
   */
}

int main()
{
   some_magic_function([] (int, double, float) {});
}

I get a compilation error saying: 'type' is not a member of any direct or indirect base class of 'make_tuple_of_params'. It seams like the SFINAE does not work as expected since the default struct is selected. How do I fix this?

like image 895
0xBADF00 Avatar asked Nov 29 '16 14:11

0xBADF00


People also ask

What is metaprogramming used for?

Metaprogramming can be used to move computations from run-time to compile-time, to generate code using compile time computations, and to enable self-modifying code. The ability of a programming language to be its own metalanguage is called reflection.

What is the point of template metaprogramming?

Template metaprogramming (TMP) is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled.

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

The type of [] (int, double, float) {} is an unnamed class type local to main, called the closure type. It is most definitely not void (int, double, float); it is in fact not a function type at all. Therefore, the specialisation for function types doesn't apply, and the primary template is selected. (Note that no SFINAE is involved in your code).

As for how to fix this: I don't think there's a fully general solution. There could be a solution/workaround for a particular some_magic_function, but that would depend on what you need that function to do.

like image 184
Angew is no longer proud of SO Avatar answered Sep 22 '22 12:09

Angew is no longer proud of SO