Is it possible to have a class with an optional template parameter that can be called like this?:
#include <iostream>
template <typename T = void>
class A final
{
public:
// This class can be called only when T exists.
void f()
{
printf("%d\n", member);
}
// This method can be called only when T is missing.
void g()
{
printf("No template parameter\n");
}
public:
T member;
};
int main()
{
A<int> a1;
A a2;
a1.f(); // should be valid
a1.g(); // should be invalid, cannot compile
a2.f(); // should be invalid, cannot compile
a2.g(); // should be valid
return 0;
}
If yes, what are the std functions that should be used?
You might use the "old" way with specialization:
template <typename T = void>
class A final // generic case, T != void
{
public:
void f() { std::cout << member << std::endl; }
public:
T member;
};
template <>
class A<void> final
{
public:
void g() { printf("No template parameter\n"); } // actually `void` and not "No".
};
By turning your class into variadic, to handle absent parameter as empty pack, instead of void, you might do:
template <typename... Ts>
class A final
{
static_assert(sizeof...(Ts) < 2);
public:
void f() requires (sizeof...(Ts) == 1) { std::cout << std::get<0>(member) << std::endl; }
void g() requires (sizeof...(Ts) == 0) { printf("No template parameter\n"); }
public:
std::tuple<Ts...> member;
};