[cfe-dev] Templated operator overloading

Nikola Smiljanic popizdeh at gmail.com
Thu May 22 16:37:30 PDT 2014


I somehow missed your reply Richard. Is the bug report I showed earlier the
same thing? And should we close it if it is?


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/cf25bb03/attachment.html>


More information about the cfe-dev mailing list