c – 为什么不能覆盖operator << for涉及第三方代码的模板
我在
https://stackoverflow.com/a/51951315/1908650中询问了以下内容:
在评论中,@ Yakk – Adam Nevraumont指出:
我正在创造一个新的Q.以接受这种报价…… 解决方法
在与类型关联的命名空间中重载运算符的适当位置.
对于std :: optional< std :: unique_ptr< T>>有一个关联的命名空间std始终存在(来自ostream和optional和unique_ptr),以及与T关联的任何命名空间.如果要为所有类型重载,与T关联的命名空间对您没用. 在std中引入新函数或重载是不合法的;在某些有限的情况下,您可以引入专业化,但这些都不适用于此.添加<<的新重载到std会使您的程序生成错误,无需诊断. 您可以(A)使用自己命名空间中的装饰unique_ptr或选项,或者(B)使用装饰的ostream,或者(C)编写格式化包装器: namespace fmt { template<class T> struct wrapper_t { T&& t; }; template<class T> struct is_wrapped:std::false_type{}; template<class T> struct is_wrapped<wrapper_t<T>>:std::true_type{}; template<class OS,class T,std::enable_if_t<!is_wrapped<OS&>{},bool> =true > auto operator<<( OS& os,wrapper_t<T>&& w ) -> decltype( os << std::forward<T>(w.t) ) { return os << std::forward<T>(w.t); } template<class OS,class T> auto operator<<( wrapper_t<OS&> os,T&& t ) -> decltype( os.t << std::forward<T>(t) ) { return os.t << std::forward<T>(t); } template<class T> wrapper_t<T> wrap(T&& t){ return {std::forward<T>(t)}; } } 然后std :: cout<< fmt :: wrap(foo)可以找到<<的重载在fmt内,如果没有找到,则调用<<关于所包含的数据. 这也支持fmt :: wrap(std :: cout)而不是包装参数.可能有错别字. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |