【问题标题】:In C++ can one rename/alias a non-namespace, non-class name?在 C++ 中,可以重命名/别名为非命名空间、非类名吗?
【发布时间】:2012-02-23 19:57:14
【问题描述】:

我有

namespace src {
   struct src_bar;
   void src_baz();
   template<class T> class src_qux;
}

我想引用为

namespace dst {
    struct dst_bar;
    void dst_baz();
    template<class T> class dst_qux;
}

表示我想从src“重命名”或“别名”或“重新标记”名称。

对于dst_bar,当然可以使用namespace dst { typedef src_bar dst_bar; }。是否有一些(非宏)等效项允许我将 src::src_baz 重命名为 dst::dst_baz 和 src::src_qux 重命名为 dst::dst_qux?

除非我弄错了,using 语句和命名空间别名都不能完成另外两个。为dst_baz() 编写模板转发函数是可能的,但需要了解src_baz 的数量。模板类型定义可以有 dst_qux&lt;T&gt;::type 是 src_qux&lt;T&gt; 但间接增加了冗长。

FWIW,我的用例是使用 C 名称,例如 somepackage_someportion_somefuncA,并提供命名空间友好的版本 somepackage::someportion::somefuncA,以便其他人可以使用 using somepackage::someportion 以简洁起见。

【问题讨论】:

  • #define 适合您吗?

标签: c++ namespaces using-declaration


【解决方案1】:

对于功能,您必须手动转发请求。对于非模板类型,您只需 typedef。对于模板类型,可以使用c++11新的using特性来为模板创建一个typedef风格的别名,如果你的编译器支持的话,否则你就基本不走运了。

【讨论】:

  • 这是我所期望的。感谢您的确认。
【解决方案2】:

不,您不能“重命名”某些内容,使其不再使用其原始名称。

但是,你可以通过诡计获得相同的效果。

首先,导入您想要在命名空间块中圈入的定义的标题:

namespace foo {
    #include "src_stuff.h"
}

现在你有了foo::src::src_bar 和朋友。

然后,随意使用typedef:

namespace bar {
    typedef foo::src::src_bar dst_bar;
}

瞧,bar::dst_bar 与 src::src_bar 相同。如果您不关心旧名称下剩余的定义,请跳过第一步,为方便起见,只需使用typedefs。毕竟,这就是他们的目的。

【讨论】:

  • 将包含的文件包含在命名空间中必然是有问题的......该头文件的实现文件将没有命名空间,因此将定义与在包含的头文件中声明的函数不同的函数。这并没有解决问题的主要部分:如何为函数和模板做相当于 typedef 的操作。
  • @DavidRodríguez-dribeas 模板实际上不会干扰typedef 方法。如果它们太长,您甚至可以使用预处理器宏。
【解决方案3】:

如果您可以接受宏的使用,那么这里有一个解决方案:

// declare this macro in some common file
#define CREATE(SCOPE) \
namespace SCOPE { \
   struct SCOPE## _bar; \
   void SCOPE## _baz(); \
   template<class T> class SCOPE## _qux; \
}

用法:

CREATE(src);
CREATE(dst);

【讨论】:

  • 感谢您提供基于宏的解决方案。
猜你喜欢
  • 2010-11-12
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
相关资源
最近更新 更多