Open Quuxplusone opened 12 years ago
Bugzilla Link | PR13869 |
Status | NEW |
Importance | P enhancement |
Reported by | Eli Friedman (efriedma@quicinc.com) |
Reported on | 2012-09-18 15:53:22 -0700 |
Last modified on | 2018-01-23 09:38:15 -0800 |
Version | trunk |
Hardware | PC All |
CC | dgregor@apple.com, llvm-bugs@lists.llvm.org, rafael@espindo.la, richard-llvm@metafoo.co.uk, ville.voutilainen@gmail.com |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
Same thing:
template <typename T, typename U>
void operator<<(T t, U u)
{
}
template <typename T>
void
operator<<(T t, int i)
{
}
struct S
{
};
int main()
{
char buf[8];
S s;
buf << s;
return 0;
}
gcc accepts, clang rejects, all the way up to the current trunk.
[over.oper]/6 says
"An operator function shall either be a non-static member function or be a non-
member function that has
at least one parameter whose type is a class, a reference to a class, an
enumeration, or a reference to an
enumeration."
I would certainly expect the violation of that "shall" to be a SFINAE
case, not a hard error.
This is not covered by SFINAE. Per [temp.deduct]p8,
"Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure."
The issue occurs when we create the declaration of the function template specialization, which happens after we've already determined the function type (which is valid and doesn't result in any kind of failure).
While I agree with Doug that clang should accept this, I don't think this code is valid per the standard as written; taking this to CWG.