I'm working on a project which has an template function as so:
template <class T>
T foo<T>(T val) { return someFunc(val); }
template <>
bool foo<bool>(bool val) { return otherFunc(val); };
Now, I have a class Bar
, which I don't want to accept as input. In fact, I want it to generate an easy to spot compile error. The problem is that if I do this:
template <>
Bar foo<Bar>(Bar val) { static_assert(false,"uh oh..."); }
It fails on every compile. I found https://stackoverflow.com/a/3926854/7673414, which says that I need to make reference to the template type, otherwise the static assert always takes place. The problem is I don't have a template type here. If I do:
template< typename T >
struct always_false {
enum { value = false };
};
template <>
Bar foo<Bar>(Bar val) { static_assert(always_false<Bar>::value,"uh oh..."); }
then it also always fails compiling. Is there a way to ensure that an instantiation of the template with type Bar
always causes a compile error?
Since foo
is a complete specialization, it will always get compiled, and the static assert will always get called.
However, there’s an easier way:
template <>
Bar foo<Bar>(Bar val) = delete;
This will say that this specific version is deleted, and cannot be called.
Another way is enable the template (not specialized version) only if the type is different from Bar
template <class T>
typename std::enable_if< ! std::is_same<T, Bar>::value, T>::type foo<T>(T val)
{ return someFunc(val); }
If you can use C++14, is can be simplified using std::enable_if_t
template <class T>
std::enable_if_t< ! std::is_same<T, Bar>::value, T> foo<T>(T val)
{ return someFunc(val); }
You can use std::is_same
to help with your requirement.
template <class T>
T foo<T>(T val)
{
// Make sure T is not Bar
static_assert(std::is_same<T, Bar>::value == false, "uh oh...");
return someFunc(val);
}
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