为什么不能在类声明中放置"using"声明?

23

我了解在头文件中放置using声明可能会遇到的问题,所以我不想这样做。 相反,我尝试将 using (或 namespace foo = )放在类声明内部,以减少头文件中的重复输入。 不幸的是,我得到了编译器错误。似乎这将是一个有用的功能。

#ifndef FOO_H
#define FOO_H

// This include defines types in namespace gee::whiz::abc::def,
// such as the class Hello.
#include "file_from_another_namespace.h"

// using namespace gee::whiz::abc::def; // BAD!

namespace x {
   namespace y {
      namespace z {

struct Foo {
    using namespace gee::whiz::abc::def; // Illegal.
    namespace other = gee::whiz::abc::def; // Illegal.

    // Foo(gee::whiz::abc::def::Hello &hello); // annoyingly long-winded

    Foo(other::Hello &hello); // better
    //...
};

} } } // end x::y::z namespace

#endif // FOO_H

在实际代码中,命名空间的名称通常更长且令人烦恼,这不是我可以改变的。

有人能解释一下为什么这不合法吗?或者(更好的是)是否有解决方法?

3个回答

26

你能执行 typedef gee::whiz::abc::def::Hello Hello 吗?


2
这仍然会污染命名空间,而这正是他试图避免的。 - Trent
8
如果它在类声明内部使用,那么不会产生影响。 - Georg Fritzsche
1
是的,那样可以!如果我将其设置为私有的typedef,那么其他代码就不会意外地使用它。 - Dan
@gf,你说得对,如果typedef在类声明内部,它就可以工作。顺便说一下,即使是我的错误,除非答案更改,否则我也无法将我的反对票更改为赞成票 :( - Trent
@Trent:您可以通过再次点击“向下”按钮来撤销对某个内容的负评。 - jamesdlin
@jamesdlin,我不能这样做,当我尝试取消踩或将其改为赞时,会显示消息:“投票时间过长,除非此答案被编辑”。我想我可以编辑答案,然后改变我的投票 :) - Trent

4

实际上并不是一个完全可怕的想法。它至少与现在的工作方式一样有意义(尽管不是很多)。我认为基本问题在于类不是编译和链接的单位,而是“翻译单元”。但逐个类地执行会更加清晰,让类成为模块,就像Java、C#或其他更有意义的语言一样。


1

有相同的问题,找到了这个问题。我发现如果你用一个匿名命名空间来包装结构体Foo,似乎可以将

using namespace too::many::names;

放在匿名包装器的顶部。虽然它有点丑陋,增加了更多的嵌套括号层次。


嗯...但是你在头文件中有一个匿名命名空间。不确定我是否想要打开那个潘多拉魔盒:https://dev59.com/RXRC5IYBdhLWcg3wROtQ https://dev59.com/NXRC5IYBdhLWcg3wROtQ - Dan
我了解到命名空间的设计是上一轮标准化中的遗憾之一,因为它被强行加入而没有太多实现经验。最近我主要使用Boost头文件库,所以在五分钟的实验中似乎可以正常工作。 - Allan Stokes
由于某些原因,在正常键入期间会触发添加评论两次。上面的链接出现了一种苏格拉底草人论法:大师很忙于炫耀,以至于没有小人物质疑为什么不允许在类范围内使用指令。昨晚我读了Bjarne写的关于概念的手写论文,感觉双方都有所启迪。但从上面的链接来看,却没有这样的效果。如果我不想让我的源代码看起来像一个繁琐冗长的SOAP数据报文呢? 是啊是啊是啊?所有的陷阱都没带电筒。 - Allan Stokes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接