仅通过其参数查找重载地址

Find an overload address by its parameters only

假设一个函数(可以是全局函数或成员函数)仅在其参数上重载(因此它的重载将始终全部为 const 或全部为非 const)。有没有办法写一个模板,根据指定的参数select重载地址?例如:

struct Foo {
    double bar(double n, double m);
    int bar(int n, int m);
};

auto addressDouble = find_overload<&Foo::bar, double, double>::address;
auto addressInt = find_overload<&Foo::bar, int, int>::address;

我发现的一个有趣的答案是 here,但不幸的是,它只处理将调用转发到正确的重载,而不是实际获取重载地址以便稍后使用。

最后一点:完美的解决方案应该适用于已发布的 Clang 版本。除此要求外,还可以使用任何可用的 C++1z 功能和更低版本。

您可以使用 static_cast<>() :

auto addressDouble = static_cast<double(*)(double, double)>(&Foo:bar);
auto addressInt = static_cast<int(*)(int, int)>(&Foo:bar);

在您可以访问重载函数的地址之前,您必须指定您需要哪个版本。

template<typename ...TA>
struct find_overload
{
    template<typename TObj, typename TR>
    using member_func_t = TR(TObj::*)(TA...);

    template< typename TObj, typename TR >
    static constexpr auto get_address(member_func_t<TObj, TR> func) -> member_func_t<TObj, TR>
    {
        return func;
    }
};

int main()
{
    constexpr auto address = find_overload<double, double>::get_address(&Foo::bar);
}

尽管@MRB ,但存在更紧凑的解决方案。
它遵循一个最小的工作示例:

#include<iostream>

struct Foo {
    double bar(double n, double m) {}
    int bar(int n, int m) {}
};

double quux(double n, double m) {}
int quux(int n, int m) {}

template<typename... A, typename T, typename R>
constexpr auto find_overload(R(T::*f)(A...)) { return f; }

template<typename... A, typename R>
constexpr auto find_overload(R(*f)(A...)) { return f; }

int main() {
    auto fooAddressDouble = find_overload<double, double>(&Foo::bar);
    auto fooAddressInt = find_overload<int, int>(&Foo::bar);
    Foo foo;
    (foo.*fooAddressDouble)(0., 0.);
    (foo.*fooAddressInt)(0, 0);

    auto globalAddressDouble = find_overload<double, double>(&quux);
    auto globalAddressInt = find_overload<int, int>(&quux);
    globalAddressDouble(0., 0.);
    globalAddressInt(0, 0);
}

如您所见,find_overload 接受自由函数和成员函数(它推导出 class 类型和 return 类型)。