Home > other >  C class template taking either type or non-type
C class template taking either type or non-type

Time:12-18

I see a few similar questions, but they don't seem to get at this.

I can overload a function on a template:

template <typename T> void foo(); // Called as e.g., foo<int>();
template <std::size_t I> void foo(); // Called as e.g., foo<2>();

Is there a way to do something similar with a class, where I can have either MyClass<int> or MyClass<2>?

I can't see a way to do it. (My real goal is to have a static constexpr instance of an invokable that acts like std::get. Whereas std::get is templated on its "indexing" parameter and on the argument type, I'd like to make one that is invokable on its own, so myns::get<2> and myns::get<int> are both invokable and when invoked act like std::get<2>(tup) and std::get<int>(tup) respectively.

Naively you'd hope something like this would work, but the auto is a type:

template <auto IndOrType>
constexpr auto get = [](auto&& tup) {
    return std::get<IndOrType>(std::forward<decltype(tup)>(tup));
};

I can make a getter function that returns a lambda, but then it's called with () as in myns::get<2>()(tup) or myns::get<int>()(tup).

CodePudding user response:

You could specialize the class using the helper type std::integral_constant<int,N>. Though unfortunately this doesn't exactly allow the MyClass<2> syntax:

#include <type_traits>

template<typename T>
class MyClass
{
};

template<int N>
using ic = std::integral_constant<int,N>;

template<int N>
class MyClass<ic<N>>
{

};

int main()
{
    MyClass<int> a;
    MyClass<ic<2>> b;
}

https://godbolt.org/z/84xoE1Yd4

  • Related