I want to do something like
template <typename T>
void foo(const T& t) {
IF bar(t) would compile
bar(t);
ELSE
baz(t);
}
I thought that something using enable_if
would do the job here, splitting up foo
into two pieces, but I can't seem to work out the details. What's the simplest way of achieving this?
EDIT: I spoke too soon! litb's answer shows how this can actually be done (at the possible cost of your sanity... :-P)
Unfortunately I think the general case of checking "would this compile" is out of reach of function template argument deduction + SFINAE, which is the usual trick for this stuff. I think the best you can do is to create a "backup" function template:
And then change
foo()
to simply:This will work for most cases. Because the
bar()
template's parameter type isT
, it will be deemed "less specialised" when compared with any other function or function template namedbar()
and will therefore cede priority to that pre-existing function or function template during overload resolution. Except that:bar()
is itself a function template taking a template parameter of typeT
, an ambiguity will arise because neither template is more specialised than the other, and the compiler will complain.bar(long)
butfoo(123)
is called. In this case, the compiler will quietly choose to instantiate the "backup"bar()
template withT = int
instead of performing theint->long
promotion, even though the latter would have compiled and worked fine!In short: there's no easy, complete solution, and I'm pretty sure there's not even a tricky-as-hell, complete solution. :(