In C++0x SFINAE rules have been simplified such that any invalid expression or type that occurs in the “immediate context” of deduction does not result in a compiler error but rather in deduction failure (SFINAE).
My question is this:
If I take the address of an overloaded function and it can not be resolved, is that failure in the immediate-context of deduction?
(i.e is it a hard error or SFINAE if it can not be resolved)?
Here is some sample code:
struct X
{
// template<class T> T* foo(T,T); // lets not over-complicate things for now
void foo(char);
void foo(int);
};
template<class U> struct S
{
template<int> struct size_map
{ typedef int type; };
// here is where we take the address of a possibly overloaded function
template<class T> void f(T,
typename size_map<sizeof(&U::foo)>::type* = 0);
void f(...);
};
int main()
{
S<X> s;
// should this cause a compiler error because 'auto T = &X::foo' is invalid?
s.f(3);
}
Gcc 4.5 states that this is a compiler error, and clang spits out an assertion violation.
Here are some more related questions of interest:
Does the FCD-C++0x clearly specify what should happen here?
Are the compilers wrong in rejecting this code?
Does the “immediate-context” of deduction need to be defined a little better?
Thanks!
This doesn’t work, because
Udoes not participate in deduction. WhileUis a dependent type, during deduction forfit’s treated like a fixed type spelled with a nondependent name. You need to add it to the parameter list offSo in your case because
U::foodoes not depend on parameters offitself, you receive an error while implicitly instantiatingS<X>(try to comment out the call, and it should still fail). The FCD says at14.7.1/1That is, if you implicitly instantiate
S<X>the following function template declaration will be instantiatedAnalysis on that template declaration will then find that it can’t resolve the reference to
X::fooand error out. If you addU1, the template declaration will not yet try to resolve the reference toU1::foo(sinceU1is a parameter off), and will thus remain valid and SFINAE whenfis tried to be called.