Понадобилось тут создавать объекты, вызывая конструкторы с неизвестным числом аргументов. И главная проблема: а сколько параметров передавать? И если для функций и методов можно взять указатель и разобрать шаблоном на кирпичики, с конструктором такое не прокатит: получить указатель на конструктор нельзя.

template <typename Return, typename Obj, typename... Args>
constexpr int number_of_arguments(Return (Obj::*fp)(Args...) const) {
  return sizeof...(Args);
}

Облегчает задачу, что сами типы аргументов конструктора известны. Они все должны выводиться из некоторого общего типа, условно, “Any”. Тогда можно пробовать вызывать конструктор с N+1 аргументами, и считать количество, с которым объекту-таки удалось создаться.

Сначала получим число параметров, рекурсивно проверяя конструктор, с каждым шагом увеличивая число параметров на один.

template <int count, typename Any, typename T, typename... Args>
constexpr auto arguments_count() -> std::enable_if_t<std::is_constructible<T, Args...>::value, int> {
    return count;
}

template <int count, typename Any, typename T, typename... Args>
constexpr auto arguments_count() -> std::enable_if_t<!std::is_constructible<T, Args...>::value, int> {
    static_assert(count < 20, "Max constructor arguments");
    return arguments_count<count + 1, Any, T, Args..., Any>();
}

С полученным числом аргументов уже можно вызывать конструктор. Но нужно как-то собрать список из Any длиной arguments_count. И если схлопнуть последовательность можно удобно через index_sequence, то чтобы расковырять её обратно без хелпера не обойтись. И трикшот с оператором запятая, чтобы вместо каждого числа подсунуть аргументом Any:

template <typename T, typename Pack>
struct Constructor;

template <typename T, std::size_t... arguments>
struct Constructor<T, std::integer_sequence<std::size_t, arguments...>> {
    template <typename Any>
    static constexpr T construct(const Any &any) {
        return T(((void)arguments, any)...);
    }
};

И, собственно, вызов:

template <typename T, typename Any>
constexpr T construct(const Any &any) {
  return Constructor<T, std::make_index_sequence<arguments_count<0, Any, T>()>>::construct(any);
}

Пример использования в реальной жизни. godbolt

struct A {
    A(int a, int b): v(a + b) {}
    int v;
};

struct B {
    int v = 1;
};

int main() {
  construct<A>(1);
  construct<B>(2);
}