Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alias template for higher-kinded types

Tags:

c++

c++11

c++14

Let's call a type that looks like T<Us...> a higher-kinded type. For a certain higher-kinded type SomeType (let's say it's std::vector<int>), I want to use type traits to extract the T part (std::vector) from it. I can do something like:

template<typename>
struct HKT;

template<template <typename...> class T, typename... Us>
struct HKT<T<Us...>> {
    template<typename... Vs>
    using type = T<Vs...>;
};

So now I can do HKT<SomeType>::type<Foo> to define an std::vector<Foo>.

But I'm trying to get rid of the ::type part, just like typename std::enable_if<T>::type can be abbreviated to std::enable_if_t<T>. Not sure if it's possible though, because in my case the HKT_t<SomeType> (assuming it exists) would be an alias template instead of a type. And the usage would be something like HKT_t<SomeType><Foo>... I guess this really is an "alias template template".

The reason I want to do this is to use it as the argument for a template template parameter. For example,

template<template <typename...> class T>
void foo() {...}

foo<HKT_t<std::vector<int>>>();

Is that possible?

like image 273
Zizheng Tai Avatar asked Nov 08 '22 13:11

Zizheng Tai


1 Answers

As chris mentioned your best option is to create a wrapper function to invoke your foo:

template <class T>
void wrapper_foo() {
   foo<T::template type>();
}

//to call foo
wrapper_foo<HKT<std::vector<int>>>();

Or make use of default value of template parameter:

template<class T, template <class...> class TT = T::template type>
void foo() {
    TT<float> t;
}

Now you could simply call:

foo<HKT<std::vector<int>>>();
like image 82
W.F. Avatar answered Nov 15 '22 13:11

W.F.