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?
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