为什么不能覆盖 operator<<;对于涉及第三方代码的模板类? [英] Why is it not possible to override operator<< for template classes involving third-party code?
问题描述
我在 https://stackoverflow.com/a/51951315/1908650 中询问了以下内容:
I asked about the following in https://stackoverflow.com/a/51951315/1908650 :
我想重载template
).
在评论中,@Yakk - Adam Nevraumont 指出:
In the comments, @Yakk - Adam Nevraumont notes:
这个问题的答案是你不能".对于泛型类型 T,没有好的合法方法可以做到这一点;我可以解释原因,但这样做需要一个新的问题/答案
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. 以接受友好的提议...
I'm creating a new Q. to take up the kind offer...
推荐答案
在与类型关联的命名空间中重载运算符的正确位置.
The proper place to overload operators in in the namespace associated with the type.
对于 std::optional<std::unique_ptr<T>>
,有一个关联的命名空间 std
始终存在(来自 ostream
和 optional
和 unique_ptr
),以及与 T
关联的任何命名空间.由于您想为所有类型重载,与 T
关联的命名空间对您没有用.
For std::optional<std::unique_ptr<T>>
there is one associated namespace std
that is always there (from ostream
and optional
and unique_ptr
), plus whatever namespace is associated with T
. As you want to overload for all types, the namespace(s) associated with T
are not useful to you.
在std
中引入新函数或重载是不合法的;在某些有限的情况下,您可以引入专业化,但它们都不适用于此处.将 <<
的新重载添加到 std
会使您的程序格式错误,无需诊断.
It is not legal to introduce a new function or overload into std
; in certain limited circumstances you can introduce specializations, but none of them apply here. Adding a new overload of <<
to std
makes your program ill formed, no diagnostic required.
您可以 (A) 使用装饰的 unique_ptr
或 optional
来自您自己的命名空间,或 (B) 使用装饰的 ostream
,或(C) 编写格式化程序包装器:
You could (A) use decorated unique_ptr
or optional
s from your own namespace, or (B) use a decorated ostream
, or (C) write a formatter wrapper:
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
中找到 <<
的重载,如果没有找到则调用 <<
包含的数据.
then std::cout << fmt::wrap( foo )
can find overloads of <<
within fmt
, and if none are found invokes <<
on the contained data.
这也支持 fmt::wrap(std::cout)
而不是包装参数.可能有错别字.
This also supports fmt::wrap(std::cout)
instead of wrapping the arguments. There are probably typos.
这篇关于为什么不能覆盖 operator<<;对于涉及第三方代码的模板类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!