Reputation: 7937
I would like to call a template function even if std::enable_if_t
doesn't resolve to true
. It would allow me to reuse one of my existent templates in other context.
Minimal example:
#include <iostream>
#include <type_traits>
template<typename T,
typename = typename std::enable_if<std::is_same<T, int>::value>::type>
auto foo(T t) {
std::cout << t << std::endl;
return t;
}
template<typename T>
auto bar(T t) {
foo(t);
}
int main() {
int i = 42;
foo(i); // ok already
// foo("42"); // shouldn't
bar("42"); // should
}
I tried to solve it bydeclaring a bool
in template argument list of foo
and specify it when calling foo
in bar
, but I didn't quite manage to compile it without changing how foo
is getting called in already existent code.
Is there any way to accomplish this? Maybe std::disjunction
?
Upvotes: 1
Views: 73
Reputation: 40013
Using this SFINAE technique, you can call foo
for “forbidden” types by not using the default template argument (and therefore not using deduction):
template<typename T>
auto bar(T t) {
return foo<T,void>(t);
}
This is of course sometimes cited as a weakness of default-type-template-argument SFINAE, along with its inability to constrain multiple, otherwise-equivalent overloads.
Upvotes: 1
Reputation: 474036
What you want doesn't make sense. Either a call to foo
is valid or it isn't. It shouldn't matter who does it. enable_if
is used to ward templates from cases where a particular parameter cannot work (or you have an alternate definition where it can). For example, if the definition is going to use a copy constructor, but the type doesn't have one. What you're using it for here doesn't fit that use case.
You can pull out the logic of foo
into a separate function that both foo
and bar
call, if you really need to do something like this.
Upvotes: 5