[cfe-dev] Templated operator overloading
Richard Smith
richard at metafoo.co.uk
Fri May 23 13:50:48 PDT 2014
On Thu, May 22, 2014 at 4:37 PM, Nikola Smiljanic <popizdeh at gmail.com>wrote:
> I somehow missed your reply Richard. Is the bug report I showed earlier
> the same thing? And should we close it if it is?
>
Yes, that bug is the same thing. I think we should extend this behavior to
C++98 mode, and then close the bug (if you're interested, look for
CPlusPlus11 in SemaTemplateDeduction; this is the second and third
occurrence).
> On Fri, May 23, 2014 at 7:45 AM, Richard Smith <richard at metafoo.co.uk>wrote:
>
>> On Thu, May 22, 2014 at 1:12 AM, <antoni at buszta.info> wrote:
>>
>>> Hi all,
>>>
>>> I have some small problem with clang behavior in such code:
>>>
>>> struct stream
>>> {
>>> stream() {}
>>> template<typename T>
>>> inline stream& operator<<(T& t)
>>> {
>>> return *this;
>>> }
>>> };
>>>
>>> template<typename Stream>
>>> inline Stream& operator<<(Stream& stream, int& t)
>>> {
>>> return stream;
>>> }
>>>
>>> int main(int argc, char *argv[])
>>> {
>>> int i = 42;
>>> stream a;
>>> a << i;
>>>
>>> return 0;
>>> }
>>>
>>> This code compiles fine under clang (I have checked with 3.4 and current
>>> trunk) and gcc. However when I add -std=c++11 it still compiles fine under
>>> gcc but it stops compiling under clang. Error is:
>>>
>>> /home/abuszta/Development/llvm/bin/clang++ -std=c++11 operator.cpp
>>> -o operator
>>> operator.cpp:21:7: error: use of overloaded operator '<<' is ambiguous
>>> (with operand types 'stream' and 'int')
>>> a << i;
>>> ~ ^ ~
>>> operator.cpp:5:20: note: candidate function [with T = int]
>>> inline stream& operator<<(T& t)
>>> ^
>>> operator.cpp:12:16: note: candidate function [with Stream = stream]
>>> inline Stream& operator<<(Stream& stream, int& t)
>>> ^
>>> 1 error generated.
>>>
>>
>> See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#532
>>
>> Deduction succeeds for both function templates, and neither candidate is
>> better than the other based on implicit conversion sequences, so we perform
>> partial ordering on the function templates. Per 14.5.6.2, we perform
>> partial ordering on these signatures:
>>
>> stream &(stream &, T &) // member
>> Stream &(Stream &, int &) // non-member
>>
>> These are unordered, so the call is ambiguous.
>>
>> In C++98 mode, we don't implement DR532, and instead only consider the
>> second parameter. That's arguably misguided, since the wording prior to
>> DR532 was simply broken (in particular, it didn't say that we ignore the
>> first parameter from the non-member, which is what we do in C++98 mode),
>> and we'd be better off using the C++11 rule rather than making up a
>> different rule.
>>
>> Apparently GCC doesn't implement DR532 in any mode.
>>
>> In order to answer the question which behavior is good and which is bad I
>>> tried to find appropriate section in C++ standard. After analyzing 14.5.6.2
>>> (section about Partial ordering of function templates in N3337) and related
>>> I think there should not be any ambiguity after substitution and function
>>> should be choosed...
>>>
>>> What is more, when I make const stream a; this code compiles fine even
>>> with -std=c++11 and chooses the standalone function in favor to member
>>> function which suggests that there may be some problem with template
>>> resolution here.
>>>
>>> What is your interpretation of this behavior? Should I report bug?
>>
>>
>> This is a GCC bug. And possibly a bug in Clang's C++98 mode, depending on
>> your point of view.
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140523/f9e41058/attachment.html>
More information about the cfe-dev
mailing list