Implicit conversion operator priority

随声附和 提交于 2019-12-05 01:07:43

Recall that std::string is not a standalone type, it's really a class template specialization - std::basic_string<char>. The very important detail is that the potential overload for streaming a std::string does not take a std::string const& argument, it is a function template that deduces a std::basic_string const&:

template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>& 
    operator<<(std::basic_ostream<CharT, Traits>& os, 
               const std::basic_string<CharT, Traits, Allocator>& str);

Template deduction never considers conversions. Name lookup will find this function template, and then discard at as being non-viable due to deduction failure. S is not a basic_string<CharT, Traits, Allocator> for any such types, so we're done. The only viable stream operators would be all the integral ones, of which bool is the best match.

If there specifically was a function with signature:

std::ostream& operator<<(std::ostream&, std::string const& );    

Then the call would be ambiguous - you'd get two user-defined conversions that would be equivalently ranked.


This is easy to verify by using our own functions instead of the million overloads for operator<<:

void foo(bool ); // #1
void foo(std::string ); // #2

void bar(bool );  // #3
template <class C, class T, class A>
void bar(std::basic_string<C,T,A> ); // #4

foo(S{}); // error: ambiguous
bar(S{}); // calls #3
ostream& operator<<( bool value );

Is a member function of std::ostream. On the other hand:

std::ostream& operator<<(std::ostream& os, const std::string& str);

Is a standalone function - which is actually declared as a template. A reference to S doesn't match any of the templates - so it isn't considered for template expansion.


It is possible to uniquely determine which overload should be selected, but I suggest you don't do that.

a) This is always one of the tricky corners of the standard (so you may encounter compiler bugs;

b) future developers will always find the code hard to read.

My suggestion is to avoid the problem entirely by just making your conversion operators explicit, or give them names like to_bool() and to_string().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!