Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>>;
like image 783
J. Doe Avatar asked May 06 '19 01:05

J. Doe


People also ask

What is an alias template?

Alias templates are a way to give a name to a family of types. Template parameters can be types, non-types, and templates themselves.

What is alias declaration in C++?

You can use an alias declaration to declare a name to use as a synonym for a previously declared type. (This mechanism is also referred to informally as a type alias). You can also use this mechanism to create an alias template, which can be useful for custom allocators.

What is member function template in C++?

Member function templates are function templates that are members of a class or class template. Member functions can be function templates in several contexts. All functions of class templates are generic but aren't referred to as member templates or member function templates.

How would you define member function outside the class template?

Member functions of class templates (C++ only) You may define a template member function outside of its class template definition. The overloaded addition operator has been defined outside of class X . The statement a + 'z' is equivalent to a. operator+('z') .


2 Answers

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

like image 195
songyuanyao Avatar answered Oct 24 '22 10:10

songyuanyao


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.

like image 27
Yakk - Adam Nevraumont Avatar answered Oct 24 '22 10:10

Yakk - Adam Nevraumont