Ну не факт что компилятор такое разложит в switch, а значит будет call, что по стоимости то же что function, а может и дороже, ведь в таблицу ещё почитать надо сходить.
Ну вот смотри. Представь, что у тебя все std::function тегированы (т.е. добавлен дополнительный шаблонный параметр), чтобы несовместимые стали несовместимыми. В этом случае компилятор за счет internal linkage параметров конструктора имеет шанс понять, что тут вызов по таблице - прийти к switch.
А если компилятор не может разложить в switch конструкцию вида
#include <array>
namespace {
void foo() {}
void bar() {}
}
int f(int n) {
constexpr std::array x = { &foo, &bar };
x[n]();
}
да еще и сгенерированную в std, это, кажется, надо писать репорт в компилятор