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