隐式转换运算符优先级 [英] Implicit conversion operator priority

查看:97
本文介绍了隐式转换运算符优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码段中(在coliru上生活):

In the following piece of code (live on coliru):

#include <iostream>
#include <string>

int main()
{
    struct S {
        operator bool        () const { return false; }
        operator std::string () const { return "false"; }
    } s;
    std::cout << s << "\n"; // outputs 0
}

编译器如何选择以选择通过std::string隐式转换为bool?

How does the compiler choose to pick the implicit conversion to bool over std::string?

我的假设是,在这种情况下,它可能纯粹是 std::basic_ostream::operator<< ,但这就是全部吗?该标准是否说明了选择特定的隐式转换?

My hypothesis is that in this case, it might be purely the order of declaration of the different flavours of std::basic_ostream::operator<<, but is it all? Does the standard say something about picking a specific implicit conversion?

推荐答案

回想一下std::string不是独立类型,它实际上是类模板专业化-std::basic_string<char>.非常重要的细节是,流std::string的潜在重载不会采用std::string const&参数,它是

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);

模板推导从不考虑转化.名称查找将找到此功能模板,然后由于推导失败而被认为不可行,将其丢弃.对于任何此类类型,S都不是basic_string<CharT, Traits, Allocator>,所以我们完成了.唯一可行的流运算符将是所有整数运算符,其中bool是最佳匹配.

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.

通过使用我们自己的函数而不是operator<<的百万重载,很容易验证:

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

这篇关于隐式转换运算符优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆