#include <iostream>
constexpr int MIN_FOO = 0, MAX_FOO = 100;
struct Foo
{
template <int N>
void operator() (char, double, bool) {std::cout << "Foo<" << N << ">(char, double, bool) called.\n";}
};
struct Bar
{
template <int N>
void operator() () {std::cout << "Bar<" << N << ">() called.\n";}
};
template <int Low, int High, typename Fun, typename... Args>
void searchBinary (int key, Fun f, Args... args)
{
constexpr int Mid = (Low + High) /2;
if (key == Mid)
{
f.template operator()<Mid>(std::forward<Args>(args)...);
}
else if (key < Mid)
{
searchBinary<Low, Mid - 1>(key, f, std::forward<Args>(args)...);
}
else
{
searchBinary<Mid + 1, High>(key, f, std::forward<Args>(args)...);
}
}
template <typename Fun, typename... Args>
void executeBinarySearch (int n, Fun f, Args... args)
{
searchBinary<MIN_FOO, MAX_FOO, Fun>(n, f, std::forward<Args>(args)...);
}
int main()
{
executeBinarySearch (99, Foo(), 'a', 1.5, true);
executeBinarySearch (99, Bar());
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKY29uc3RleHByIGludCBNSU5fRk9PID0gMCwgIE1BWF9GT08gPSAxMDA7CgpzdHJ1Y3QgRm9vCnsKCXRlbXBsYXRlIDxpbnQgTj4KCXZvaWQgb3BlcmF0b3IoKSAoY2hhciwgZG91YmxlLCBib29sKSB7c3RkOjpjb3V0IDw8ICJGb288IiA8PCBOIDw8ICI+KGNoYXIsIGRvdWJsZSwgYm9vbCkgY2FsbGVkLlxuIjt9Cn07CgpzdHJ1Y3QgQmFyCnsKCXRlbXBsYXRlIDxpbnQgTj4KCXZvaWQgb3BlcmF0b3IoKSAoKSB7c3RkOjpjb3V0IDw8ICJCYXI8IiA8PCBOIDw8ICI+KCkgY2FsbGVkLlxuIjt9CQp9OwoKCnRlbXBsYXRlIDxpbnQgTG93LCBpbnQgSGlnaCwgdHlwZW5hbWUgRnVuLCB0eXBlbmFtZS4uLiBBcmdzPgp2b2lkIHNlYXJjaEJpbmFyeSAoaW50IGtleSwgRnVuIGYsIEFyZ3MuLi4gYXJncykKewogICAgY29uc3RleHByIGludCBNaWQgPSAoTG93ICsgSGlnaCkgLzI7CiAgICBpZiAoa2V5ID09IE1pZCkKICAgIHsKICAgICAgICBmLnRlbXBsYXRlIG9wZXJhdG9yKCk8TWlkPihzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogICAgfQogICAgZWxzZSBpZiAoa2V5IDwgTWlkKQogICAgewogICAgCXNlYXJjaEJpbmFyeTxMb3csIE1pZCAtIDE+KGtleSwgZiwgc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzZWFyY2hCaW5hcnk8TWlkICsgMSwgSGlnaD4oa2V5LCBmLCBzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogICAgfQp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRnVuLCB0eXBlbmFtZS4uLiBBcmdzPgp2b2lkIGV4ZWN1dGVCaW5hcnlTZWFyY2ggKGludCBuLCBGdW4gZiwgQXJncy4uLiBhcmdzKQp7CiAgICBzZWFyY2hCaW5hcnk8TUlOX0ZPTywgTUFYX0ZPTywgRnVuPihuLCBmLCBzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwp9CgppbnQgbWFpbigpCnsKCWV4ZWN1dGVCaW5hcnlTZWFyY2ggKDk5LCBGb28oKSwgJ2EnLCAxLjUsIHRydWUpOwogICAgZXhlY3V0ZUJpbmFyeVNlYXJjaCAoOTksIEJhcigpKTsgICAgCn0=