其他答案已经提供了原因,如果不是理由的话:
Atypedef
是类型的别名,编译器会将其解析为实际类型。依赖于参数的查找是基于基础类型完成的,而不是 typedef。
这个设计决策的基本原理实际上是 ADL 在语言中的原因。ADL 被添加到语言中以支持运算符重载。在任何其他用例中,用户可以显式声明函数的命名空间,但在运算符重载的情况下,这将导致反直觉的复杂代码:
std::string s("Hi");
std::cout.operator<<(s); // or is it std::operator<<(std::cout,s)??
So the language added rules for lookup to find operators (and functions) in different namespaces, and in particular in the namespace of the arguments to the function. In this case inside std::
in case the operator<<
that takes a std::string
is not a member of std::cout
. The same behavior is extended to all free functions in the same namespace (why not?) allowing the interface of a type to include not only member functions but also free functions in the same namespace.
Now if you focus on this, the purpose is accessing functions that are part of the interface of the type, and those are defined with the type. When you add a typedef in a different namespace you are just creating a shorthand to refer to the original type. All of the functions that were provided with the type (for example operator<<(std::ostream&,MyType)
) are in the original namespace, no in the namespace of the typedef
. You want ADL to look into the namespace where the real type was defined, not where the alias was created.