从函数的 return 类型推断 return 语句中的函数模板参数

Infer function template arguments in return statement from the function's return type

我有一个 return 模板 class 的函数。 在此函数中,return 语句调用创建模板实例的模板函数 class。在以下情况下,是否可以推断出模板函数的模板参数?

#include <utility>
#include <variant>

template <class T, class U>
auto make(T&& t) -> std::variant<T, U> {
    return std::variant<T, U>{ std::forward<T>(t) };
}

auto foo() -> std::variant<int, char> {
    return make<int, char>(42);  // return make(42); instead?
}

您可以 make 将您提供的任何内容包装在一个对象中,该对象可以转换为 std::variant 所需的专业化:

template<typename T>
struct make {
    make(T &&x) : x(x) { }
    T &x;
    template<typename... Us>
    operator std::variant<T, Us...>() {
        return std::forward<T>(x);
    }
};
template<typename T>
make(T&&) -> make<T>;

你能得到的最接近的是非常可怕的(并且依赖于 foo 没有被超载):

template<class F> using return_t=…;  // exercise
template<class R> using make_t=
  R (&)(std::variant_alternative_t<0,R>&&);
template<auto &F>
constexpr make_t<return_t<std::remove_reference_t<decltype(F)>>>
  make_for=make;

auto foo() -> std::variant<int, char> {
    return make_for<foo>(42);
}

std::variant_alternative_t 的少量泛化当然是可能的,但是由于您必须在模板中显式命名 make(因为函数模板和重载集不能作为模板参数),尚不清楚会增加什么。