可以将一个函数导入命名空间,但不导出它吗?

7

是否可以将一个函数(或其他符号)导入到命名空间中,但不导出它?例如,我想将std::string导入到当前命名空间中,但我不希望current::string可见。

namespace current {
  using std::string;
  string func();
}

current::string 不应该存在。

它的使用场景很简单,就是为了减少打字(避免反复输入诸如 std::string 之类的代码),同时也使代码更加清晰易读,避免命名空间语法过多干扰代码可读性。


2
在我看来,最好还是习惯于指定命名空间,特别是对于像 std 这样的小东西。当然,如果你有三四个命名空间深度并需要使用一些东西,则导入命名空间可能很好。但这并不是一个真正的答案。 - Tas
1
如果命名空间语法“混淆了代码”,那么命名空间可能不是一个好的设计决策?许多嵌套的命名空间通常不是一个好主意。 - user2100815
@RemyLebeau,请不要根据您自己的文体倾向编辑我的问题。 - JasonN
@JasonN 这不仅是为了风格和可读性,还有纠正一些拼写错误。你应该感激这里有人关心校对。你不是唯一一个会阅读这个问题的人。 - Remy Lebeau
@remylebeau,拼写错误可以修正,但是在其他地方删除缩略语并使写作更加正式并不代表我的风格。请不要认为你在帮我一个忙。Stack Overflow已经有足够的自命不凡了,不需要人们四处编辑风格。 - JasonN
3个回答

5
是否可以将函数(或其他符号)导入命名空间但不导出它?
不行。
使用using指令将引入所有符号,这些符号与您在声明中使用的名称相关,并且对于current的用户来说,它们会像实际在命名空间本身中声明一样可见。
标准的相关部分在[namespace.udir]/1中: using指令指定提名命名空间中的名称可以在using指令出现后的范围内使用。在未经限定的名称查找(6.4.1)期间,这些名称似乎是在包含using指令和提名命名空间的最近封闭命名空间中声明的。【注:在此情况下,“包含”意味着“直接或间接包含”。-结束注】

2

“计算机科学中的所有问题都可以通过引入另一层间接性来解决” - 大卫·惠勒

在这种情况下,确实如此:

namespace current {
    namespace impl {
        using std::string;
        string func();
    }

    using impl::func;
}

不可否认,这种方法有成本:

  • 它强制你列出每个你想从 current 导出的类型或函数,因为在 C++ 中没有办法从例如 using namespace 排除特定符号。(将其视为一项功能,因为它使您的 API 内容是故意的而不是偶然的。)
  • 如果需要保持 ABI 兼容性,这种方法将不起作用(我所知道的所有实现中,func 的 mangled 名称将会更改)

顺便说一下,命名空间 current 的名称表明您可能也考虑了版本控制。两种方法可以很好地结合使用,例如:

namespace _v1 {
    namespace impl {
        int func();
    }

    // Exports
    using impl::func;
}
namespace _v2 {
    namespace impl {
        using std::string;
        string func();
    }

    // Exports
    using impl::func;
}

namespace current = _v2;

嘿,不错的方法,而且注意事项讲解得很清楚。 - Lightness Races in Orbit
我希望我能接受两个答案。虽然我不会使用这个巧妙的技巧,但我没有考虑版本控制,但我会记住这个技巧,以备将来需要时使用。 - JasonN

-1
不行,你的代码是不好的实践。虽然你特定的std::string示例可能不会引起冲突,但未命名的查找可能会拉取到其他string在命名空间范围之外定义的引用,导致可能的重新声明错误或未命名的查找使用与您打算的名称不同的名称。例如,这可能发生在以下情况下:a)您或代码中的其他人使用与库(如distance)冲突的名称,b)库使用冲突的名称(如Boost),c)或不同的翻译单元从外部作用域中提取不同的名称,导致类似的代码具有完全不同的行为。
要么始终完全限定您的声明,要么至少使用using ::std::string

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