Taylor
Taylor

Reputation: 2085

Allowing class template's template parameters to be visible in the derived class

I want to preserve visibility of a class template's parameter arguments when I inherit from it. The base class will have a large number of template arguments, so I don't want to keep asking for those in the derived class templates. Is the only way to do this with type aliases?

For example, this doesn't work, but it does if I swap everything out for the commented lines:

#include <iostream>

template<typename one, typename of, typename very, typename many, typename tparams>
class first {
// public:
//  using A = one; //needs to be uncommented to work
};

template<typename class_instance>
class second : public class_instance {
    typename class_instance::one m_data;
    //typename class_instance::A m_data; // would work if we uncommented
};


int main() {

    second<first<int,int,int,int,int>> thing;

    return 0;
}

Upvotes: 1

Views: 178

Answers (1)

NathanOliver
NathanOliver

Reputation: 180955

You can save kind of make it easier by using a variadic template template parameter. Changing second to be

template<template<typename...> typename class_instance, typename... Params>
class second  {
public:
    template <std::size_t I>
    using param_t = std::tuple_element_t<I, std::tuple<Params...>>;
    param_t<1> foo;
};

You can use it like

int main() {
    second<first, int, double, float, long, long long> foo{};
    foo.foo = 42.1;
    std::cout << foo.foo;
}

which outputs

42.1

as you can see in this live example.

Yes, you are now using a number, which might not be worth it, but it removes a lot of the boiler plate. If you really want you can even add an enum to second and use it like

template<template<typename...> typename class_instance, typename... Params>
class second  {
public:
    enum { one, of, very, many, tparams };
    template <std::size_t I>
    using param_t = std::tuple_element_t<I, std::tuple<Params...>>;
    param_t<of> foo;
};

Upvotes: 2

Related Questions