bremen_matt
bremen_matt

Reputation: 7367

function return type with a different template parameter

I have some C++ classes that all have the same template parameters

template <typename T, size_t i>
struct A {

};

template <typename T, size_t i>
struct B : A<T,i>{

};

template <typename T, size_t i>
struct C : A<T,i>{

};

and so on. I also have a series of methods that will work on any of these classes. However, the problem is in the return type. I would like this method to return an instance of the passed in class, with the integer decremented by one. For instance, if I just overload the function, that would look like this

template <typename T, size_t i>
A<T,i-1> func(const A<T,i> & a){

}

template <typename T, size_t i>
B<T,i-1> func(const B<T,i> & a){

}

template <typename T, size_t i>
C<T,i-1> func(const C<T,i> & a){

}

Is there a way to accomplish this without overloading the function for each type? By that I mean... is it possible to replace these with a single templated function? The logic is identical for all of the functions.

I imagine that that would look something like

template <typename P, size_t i>
P<i-1> func( const P<i> & p ){

}

where P somehow captures the original type A, B, or C, as well as the inner type T.

Or, if you think CRTP is the way to go, then how would I structure that?

Upvotes: 5

Views: 303

Answers (2)

Red.Wave
Red.Wave

Reputation: 4258

I don't normally use the template template syntax. In case template type definitions are recursive, I'd rather stick with the old school way:

template<typename T, int I>
struct A{
    using Other=A<T,I-1>;
};
template<typename P>
typename P::Other f(P);

Upvotes: 0

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29032

It sounds like you need to use a template template parameter. These template parameters are themselves class templates. In the following example, P is a template parameter which expects a class template where that class template expects a type argument followed by a size_t argument (such as the class templates A, B or C you provided):

template<template<class, size_t> class P, class T, size_t i>
P<T, i - 1> my_func(const P<T, i> & my_P);

int main()
{
    A<int, 10> a;
    B<char, 3> b;
    C<double, 7> c;

    auto smaller_a = my_func(a); // is a A<int, 9>
    auto smaller_b = my_func(b); // is a B<char, 2>
    auto smaller_c = my_func(c); // is a C<double, 6>
}

Since you did not explain what your function should actually do, I've just provided the function declaration and left out the definition.

C++11 compilation demonstration : https://godbolt.org/g/zpXVEb

Upvotes: 8

Related Questions