J. Doe
J. Doe

Reputation: 702

alias template for member template

let's say I have a template:

template<typename T>
struct Outer {
    template<typename T1>
    struct Inner {

    };
};

I'd like to have an alias template Alias:

template<typename T>
using Alias = Outer<T>::template Inner; // this won't work

using IntOuter = Alias<int>;

so that IntOuter<double> is same as Outer<int>::template Inner<double>. How do you define Alias? Or is it possible?

Edit:

I'd like to be able to create SomeOuter on the fly so that for template foo:

template<template<typename> class>
struct Foo {
};

Foo<Alias<int>> is same as Foo<Outer<int>::template Inner>

Or to do something like this:

template<typename T>
using SomeFoo = Foo<Alias<T>>;

Upvotes: 5

Views: 201

Answers (2)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275966

You cannot do what you are asking.

That is the answer to your question. You ask a narrow question without sufficient background, that is the best I can do.


If you want to do serious metaprogramming in C++, you can transfer templates to types or values. See the boost hana library for one approach.

But none will interact with

template<template<typename> class>
struct Foo {
};

"Out of the box".

template<class T>struct tag_t{using type=T;};
template<class T>constexpr tag_t<T> tag{};
template<template<class...>class Z>struct ztemplate_t{
  template<class...Ts>using apply=Z<Ts...>;
  template<class...Ts>
  constexpr tag_t<Z<Ts...>> operator()(tag_t<Ts>...)const{return {};}
};
template<template<class...>class Z>constexpr ztemplate_t<Z> ztemplate{};
template<class Tag>using type_t=typename Tag::type;
#define TYPE(...) type_t<decltype(__VA_ARGS__)>

Now

template<typename T>
constexpr auto Alias = ztemplate<Outer<T>::template Inner>;

is now a value that acts like a template.

Mapping Foo to:

template<template<class...>class Z>
constexpr tag_t<Foo<Z>> foo( ztemplate_t<Z> ){return {};}

lets you do TYPE( foo(Alias( tag<int> ) ) ).

This is probably not what you want.

Upvotes: 1

songyuanyao
songyuanyao

Reputation: 173044

You could

template<typename T, typename T1>
using Alias = typename Outer<T>::template Inner<T1>;

template<typename T1>
using IntOuter = Alias<int, T1>;

Or directly

template<typename T1>
using IntOuter = Outer<int>::Inner<T1>;

Then for IntOuter<double> you'll get Outer<int>::Inner<double>.

LIVE

Upvotes: 4

Related Questions