I am attempting to use SFINAE to limit the allowable template parameter types for a class I am writing. Here is a simple contrived example I came up with that I believe illustrates what I would like to do.
I am sure this question is answered somewhere already, but I could not find it.
Here are two ways I have found to solve the problem:
First (SFINAE):
template <typename T, typename = typename std::enable_if<std::is_same<T, int>::value>::type>
class Integer {
public:
T value;
};
int main() {
Integer<int> i; // Alowed
Integer<double> d; // Not allowed
Integer<double, double> dd; // Allowed (Undesired)
return 0;
}
What I don't like about this solution is that the third example in the main function works.
Second (static_assert):
#include <type_traits>
template <typename T>
class Integer {
static_assert(std::is_same<T, int>::value, "T must be int");
public:
T value;
};
int main() {
Integer<int> i; // Allowed
Integer<double> d; // Not allowed
return 0;
}
I think this solution is fine, but I was wondering if there is a more elegant or SFINAE way of accomplishing the same thing.
In this case, I would like to be able to enforce that the template type T must be integer for this simple example. Of course, in this case the class does not even need to be a template and I could just declare the type inside the Integer class to be of type int, but I want to use what I learn here in a more complex situation.
static_assert
solution just fine: if a user of your class tries and useInteger<float>
, they get a nice compilation error instead of an ugly sfinae-related wall of text. – Prioress