在这篇文章中,建议使用以下方法为operator<<
定义dump()
成员函数的所有类定义函数:
templateauto operator<< (std::basic_ostream & str, const T & t) -> decltype(t.dump(str)) { return t.dump(str); }
为什么这个函数模板没有捕获所有类型,包括那些没有定义dump
成员函数的类型?我的意思是,是否在选择过载时考虑了函数签名的返回类型部分?
返回类型本身无关紧要.当声明对实例化无效时,所提出的技术依赖于SFINAE(替换失败不是错误)来删除重载.也就是说,当编译器尝试operator<<()
使用T
没有可访问dump(str)
成员的类型实例化上述内容时,decltype(t.dump(str))
将无效.而不是失败它决定这个重载将不起作用并将其从候选重载集中删除.
收集候选人后,重载解决方案会选择最佳选项.如果最佳选项是唯一的,则选择它进行调用.如果没有拟合选项或有多个最佳匹配,那将是一个错误.