具有来自另一个命名空间的 typedef 的 ADL
我有这样的事情:
#include <iostream>
namespace N
{
typedef std::pair<int, double> MyPair;
std::ostream& operator << (std::ostream& o, MyPair const & mypair)
{
///
}
}
int main()
{
N::MyPair pr;
std::cout << pr;
}
这自然行不通,因为 ADL 找不到 operator<<
因为 namespace N
与 MyPair
没有关联代码>(不幸的是)。据我所知,可能不会添加到命名空间 std,因此如果我选择在 std 中定义运算符 <<,那将是一种非法。那么...遇到这种情况该怎么办?我不想显式限定operator <<
,也不希望编写using namespace N
。那么问题来了:
- 如何重构代码?
- 为什么 ADL 不关联 typedef 的命名空间?严重的原因吗?例如在这种情况下,那就太好了。谢谢
I have something like this:
#include <iostream>
namespace N
{
typedef std::pair<int, double> MyPair;
std::ostream& operator << (std::ostream& o, MyPair const & mypair)
{
///
}
}
int main()
{
N::MyPair pr;
std::cout << pr;
}
This naturally doesn't work, because ADL won't find operator<<
because namespace N
is not associated with MyPair
(unfortunately). Afaik one may not add to namespace std, so if I chose to define operator <<
in std that would be kinda illegal. So... what to do in such situations? I don't want to explicitly qualify operator <<
, nor do I wish to write using namespace N
. So, questions are:
- How to refactor the code?
- Why wouldn't ADL associate namespaces of typedefs? Serious reasons? It would be nice, e.g. in this case. Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以在命名空间 N 中创建自己的类型,可能继承自 std::pair。您可以添加“using namespace N;”里面主要.前者更有可能有用。
因为类型是在另一个命名空间中定义的,不能分两个定义。
示例:
如果用作 std::pair 并不重要,则可以删除继承并重命名成员。当然,在任何一种情况下,您都可以添加其他方法,但如果保留继承,则可以使用“重命名方法”:
You could create your own type in namespace N, possibly inheriting from std::pair. You could add "using namespace N;" inside main. The former is more likely to be useful.
Because the type is defined in another namespace and cannot be defined in two.
Example:
If being used as a std::pair isn't important, you can drop the inheritance and rename the members. In either case you can, of course, add additional methods, but if you keep the inheritance you can use "renaming methods":
我想不出
typedef
名称不应该参与 ADL 的原因。此外,它还定义了以下代码实现:std::vector::iterator
是位于 std 命名空间中的某个内容的 typedef:std::for_each
将被调用std::vector::iterator
是my::A *
的 typedef:编译器应该抱怨my:: for_each
不接受 3 个参数I can't think of a reason why
typedef
names should not participate in ADL. Furthermore, it makes the following code implementation defined :std::vector<T>::iterator
is a typedef for something which sits in the std namespace :std::for_each
will be calledstd::vector<T>::iterator
is a typedef formy::A *
: the compiler should complain thatmy::for_each
doesn't take 3 arguments您的选择是:
pair
是否算作 UDT)这一切都源于 typedef 的主要优点和缺点:typedef 名称只是同义词。无论您将其放入哪个命名空间,typedef 名称都会引用关联的类型,无论该类型是在哪个命名空间中定义的。这与 typedef 不同,typedef 是可与关联类型相互转换的新类型。想象一下这种情况:
这是无效的,因为 int 和 id_t 不是不同的类型。这延伸到 ADL:
这里有一个问题要问你:你认为以下内容应该无法编译吗?如果没有,应该如何解决名称查找:
Your options are to:
pair<int,double>
counts as a UDT)This all stems from the main strength and weakness of typedefs: typedef names are just synonyms. It doesn't matter what namespace you put it in, the typedef name refers to the associated type, in whatever namespace that type is defined in. This is distinct from a typedef being a new type that is convertible to/from the associated type. Imagine this scenario:
This is invalid, because int and id_t aren't distinct types. This extends to ADL:
And here's a question for you: Do you believe that the following should fail to compile? If not, how should the name lookup be resolved:
我通过将相关符号拉入我想要使用它们的命名空间来解决这个问题:
I solve this problem by pulling the relevant symbol(s) into the namespace I want to use them from:
您可以使用强类型定义:(
额外的类型定义仍然是必要的,以避免宏中出现额外的逗号。)
You can use a strong typedef:
(The extra typedef is still necessary to avoid the extra comma in the macro.)
如果您想要输出特定的数据类型,您始终可以定义自己的类,而不是使用
std::pair
。If you have a specific data type which you want to output, you can always define your own class rather than use
std::pair
.允许向
namespace::std
添加模板函数的专门化,但是由于MyPair
中使用的类型都不是用户定义的,我不确定这样的专业化是否合法。It is allowed to add specialization of template functions to
namespace::std
however since none of the types used inMyPair
is user defined I'm not sure such a specialization is legal.