It seems to be simple, but I have some difficulties with the syntax of std::enable_if
The situation is actually quite simple.
a template class with template parameter T
2 functions which shall not be implemented for one specific type of T
.
Both functions have no parameters or return values of T
One function accepts an int
and the other function returns an int
.
Any simple example ?
Or is there another option (C++11) which does not use std::enable_if
?
It's really simple. Just remember to use another template parameter that is defaulted to the class/struct template parameter.
Suppose you want a class foo<T>
with two members, void foo<T>::bar1 (int)
and int foo<T>::bar2 ()
and suppose that you want that bar1()
and bar2()
are implemented only if T
is different from long
.
You can do as follows
#include <type_traits>
template <typename T>
struct foo
{
template <typename U = T>
typename std::enable_if<false == std::is_same<U, long>::value>::type
bar1 (int)
{ }
template <typename U = T>
typename std::enable_if<false == std::is_same<U, long>::value, int>::type
bar2 ()
{ return 0; }
};
int main()
{
foo<int> fi;
foo<long> fl;
fi.bar1(0); // compile
fi.bar2(); // compile
// fl.bar1(0); // compilation error
// fl.bar2(); // compilation error
}
There is a danger: someone can bypass your control and explicit the U
type as follows
foo<long> fl;
fl.bar1<long long>(0);
To avoid this problem, you can improve your std::enable_if
test as follows
template <typename U = T>
typename std::enable_if
<sizeof(U) && (false == std::is_same<T, long>::value)>::type
bar1 (int)
{ }
template <typename U = T>
typename std::enable_if
<sizeof(U) && (false == std::is_same<T, long>::value), int>::type
bar2 ()
{ return 0; }
If you can use a C++14 compiler, using std::enable_if_t
you can avoid a couple of typename
and a couple if ::type
and semplify the code as follows
template <typename U = T>
std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value)>
bar1 (int)
{ }
template <typename U = T>
std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value), int>
bar2 ()
{ return 0; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With