c++overloadingresult-of

Using std::result_of with an overloaded method


I added an overloaded method to an existing class, which now causes a compilation error in our unit tests.

I have replicated the issue with the following code:

#include <type_traits>
#include <string>

class Foo
{
    public:
    Foo() {};
    int bar(const std::string & s) {return 1;};
    int bar(const std::string & s, long l) {return 2;};
    int bar2(const std::string & s) {return 3;};
};

int main()
{
    // compiles
    std::is_same<std::result_of<decltype(&Foo::bar2)(Foo, const std::string &)>::type, int>::value;

    // does not compile
    std::is_same<std::result_of<decltype(&Foo::bar)(Foo, const std::string &)>::type, int>::value;
    return 0;
}

What changes do I need to make to the line that does not compile so that I can test the return of an overloaded method?


Solution

  • An overloaded function name represents all overloads, each having its own address. Thus it cannot be resolved to a certain overload unless there exists a supporting context, e.g., a static cast is used:

    static_cast<int(Foo::*)(const std::string&)>(&Foo::bar)
    

    This, however, requires you to know the exact signature, which contradicts the goal of finding the return type. Instead, you can query the return type using the decltype specifier and a helper declval function:

    std::is_same<decltype(std::declval<Foo&>().bar("")), int>::value