确定选择了哪个过载

Bar*_*rry 13 c++ overload-resolution c++11

假设我有一些任意复杂的重载函数:

template <class T> void foo(T&& );
template <class T> void foo(T* );
void foo(int );
Run Code Online (Sandbox Code Playgroud)

我想知道,对于给定的表达式, foo()被调用.例如,给定一些宏WHICH_OVERLOAD:

using T = WHICH_OVERLOAD(foo, 0);       // T is void(*)(int);
using U = WHICH_OVERLOAD(foo, "hello"); // U is void(*)(const char*);
// etc.
Run Code Online (Sandbox Code Playgroud)

我不知道我会在哪里使用这样的东西 - 我只是好奇它是否可能.

sky*_*ack 0

我可能与你的想法相去甚远,但我已经花了很多时间在这上面,值得添加一个答案(也许确实是一个完全错误的答案):

#include<type_traits>
#include<utility>

template <class T> void foo(T&&);
template <class T> void foo(T*);
void foo(int);

template<int N>
struct choice: choice<N+1> { };

template<>
struct choice<3> { };

struct find {
    template<typename A>
    static constexpr
    auto which(A &&a) {
        return which(choice<0>{}, std::forward<A>(a));
    }

private:
    template<typename A>
    static constexpr
    auto which(choice<2>, A &&) {
        // do whatever you want
        // here you know what's the invoked function
        // it's template<typename T> void foo(T &&)
        // I'm returning its type to static_assert it
        return &static_cast<void(&)(A&&)>(foo);
    }

    template<typename A>
    static constexpr
    auto which(choice<1>, A *) {
        // do whatever you want
        // here you know what's the invoked function
        // it's template<typename T> void foo(T *)
        // I'm returning its type to static_assert it
        return &static_cast<void(&)(A*)>(foo);
    }

    template<typename A>
    static constexpr
    auto
    which(choice<0>, A a)
    -> std::enable_if_t<not std::is_same<decltype(&static_cast<void(&)(A)>(foo)), decltype(which(choice<1>{}, std::forward<A>(a)))>::value, decltype(&static_cast<void(&)(A)>(foo))>
    {
        // do whatever you want
        // here you know what's the invoked function
        // it's void foo(int)
        // I'm returning its type to static_assert it
        return &foo;
    }
};

int main() {
    float f = .42;
    static_assert(find::which(0) == &static_cast<void(&)(int)>(foo), "!");
    static_assert(find::which("hello") == &static_cast<void(&)(const char *)>(foo), "!");
    static_assert(find::which(f) == &static_cast<void(&)(float&)>(foo), "!");
    static_assert(find::which(.42) == &static_cast<void(&)(double&&)>(foo), "!");
}
Run Code Online (Sandbox Code Playgroud)

我会在短时间内删除这个答案,在此期间我希望专家们诅咒我。:-)