I tried compiling the following program in Visual Studio 2013 and got the C2686: cannot overload static and non-static member functions
error.
#include <iostream>
#include <type_traits>
struct foo
{
template<bool P>
static std::enable_if_t<P> bar()
{
std::cerr << "P is true\n";
}
template<bool P>
std::enable_if_t<!P> bar()
{
std::cerr << "P is false\n";
}
};
int main()
{
foo f;
f.bar<true>();
}
I'm familiar with this compiler error—see this StackOverflow answer, but was surprised to see the error in conjunction with SFINAE, whereby the compiler will always discard one of the two overloads from the overload set.
Is Visual Studio 2013 correctly following the standard here, or should it be possible to overload on static in conjunction with SFINAE?
EDIT: Contrast example above with overloading on return type
Without SFINAE, you can't overload on static
, and you also can't overload on return type. However, Visual Studio 2013 supports overloading on return type in conjunction with SFINAE.
The following program, which is the same as the program above but removes static
and changes the return type for the second foo::bar
declaration, compiles correctly.
#include <iostream>
#include <type_traits>
struct foo
{
template<bool P>
std::enable_if_t<P> bar()
{
std::cerr << "P is true\n";
}
template<bool P>
std::enable_if_t<!P, int> bar()
{
std::cerr << "P is false\n";
return 42;
}
};
int main()
{
foo f;
f.bar<true>();
}
It seems to me Visual Studio 2013 is getting one of these two cases wrong, but I'm hoping a language lawyer can provide a definite answer.
Surprisingly enough, MSVC is correct. (I know, shock.) [over.load]/p1-2:
The two
bar()
declarations have the same name, same parameter-type-list, and same template parameter list, at least one of which isstatic
, and therefore cannot be overloaded.