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;
}
