c – 为什么不能覆盖operator << for涉及第三方代码的模板类?

前端之家收集整理的这篇文章主要介绍了c – 为什么不能覆盖operator << for涉及第三方代码的模板类?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在 https://stackoverflow.com/a/51951315/1908650中询问了以下内容

I want to overload template<class T> ostream& operator<<(ostream& os,const optional<unique_ptr<T>>&).

评论中,@ Yakk – Adam Nevraumont指出:

The answer to that question is “you cannot”. There is no good legal way to do that for a generic type T; I could explain why,but it would take a new question/answer to do so

我正在创造一个新的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)而不是包装参数.可能有错别字.

原文链接:https://www.f2er.com/c/110927.html

猜你在找的C&C++相关文章