I want to do something like
template
void foo(const T& t) {
IF bar(t) would compile
bar(t);
ELSE
baz(t);
}
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:
template
void bar(T t) { // "Backup" bar() template
baz(t);
}
And then change foo()
to simply:
template
void foo(const T& t) {
bar(t);
}
This will work for most cases. Because the bar()
template's parameter type is T
, it will be deemed "less specialised" when compared with any other function or function template named bar()
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 type T
, an ambiguity will arise because neither template is more specialised than the other, and the compiler will complain.bar(long)
but foo(123)
is called. In this case, the compiler will quietly choose to instantiate the "backup" bar()
template with T = int
instead of performing the int->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. :(