Reputation: 814
I want the class member variable only_if_int
to be defined only if the class is instantiated with the template type int. I have a working solution, but it is too verbose.
#include <iostream>
#include <type_traits>
template<typename T, typename Enable = void>
class MyClass;
template<typename T>
class MyClass<T, std::enable_if_t<std::is_same<T, int>::value>>{
public:
int common;
int only_if_int;
MyClass()
{
common = 0;
only_if_int = 0;
}
void alter_values()
{
common++;
only_if_int++;
}
};
template<typename T>
class MyClass<T, std::enable_if_t<!std::is_same<T, int>::value>>{
public:
int common;
MyClass()
{
common = 0;
}
void alter_values()
{
common++;
}
};
int main()
{
MyClass<int> int_class;
MyClass<float> float_class;
int_class.alter_values();
float_class.alter_values();
std::cout<<"\n int_class "<<int_class.common<<" "<<int_class.only_if_int;
std::cout<<"\n int_class "<<float_class.common<<" ";
return 0;
}
In the above code, the templated class MyClass
is defined twice(too much code duplicate). For eg: alter_values function is written twice. Is there a less verbose way, maybe with the help of constexpr std::is_same<T, int>
or a different C++ feature to do the same thing?
Upvotes: 1
Views: 92
Reputation: 60218
One approach would be to have a type that contains an int
member only if it's instantiated with int
, like this:
template<typename>
struct OnlyInt {};
template<>
struct OnlyInt<int> {
int only_if_int;
};
Then MyClass
can just inherit from this type:
template<typename T>
class MyClass : public OnlyInt<T> {
public:
int common;
// ... contains only_if_int if T == int
};
Now all uses of only_if_int
will need to be wrapped in an if constexpr
, and you have to use this->
to indicate that the member is from a base class. So for example:
only_if_int = 0;
becomes:
if constexpr (std::is_same_v<T, int>)
this->only_if_int = 0;
etc.
Here's a demo.
Upvotes: 1