YSC*_*YSC 11 c++ standards casting operator-overloading overload-resolution
在下面的代码中(在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
}
Run Code Online (Sandbox Code Playgroud)
编译器如何选择隐式转换为boolover std::string?
我的假设是,在这种情况下,它可能纯粹是不同口味的宣告顺序std::basic_ostream::operator<<,但这一切都是什么?标准是否说明了选择特定的隐式转换?
Bar*_*rry 11
回想一下,这std::string不是一个独立的类型,它实际上是一个类模板专业化 - std::basic_string<char>.非常重要的细节是流式传输的潜在重载std::string不带std::string const&参数,它是一个函数模板,推导出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);
Run Code Online (Sandbox Code Playgroud)
模板扣除从不考虑转换.名称查找将找到此功能模板,然后由于扣减失败而丢弃为不可行.对于任何这样的类型S都不是basic_string<CharT, Traits, Allocator>,所以我们已经完成了.唯一可行的流运营商将是所有不可或缺的运营商,其中bool最佳匹配.
如果特定的是带签名的函数:
std::ostream& operator<<(std::ostream&, std::string const& );
Run Code Online (Sandbox Code Playgroud)
然后调用将是模糊的 - 您将获得两个等效排名的用户定义转换.
这很容易通过使用我们自己的函数而不是百万次重载来验证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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
559 次 |
| 最近记录: |