有没有办法弃用命名空间?

时间:2014-04-02 09:21:21

标签: c++ gcc namespaces clang

简短:有没有办法在gcc或clang中弃用命名空间?

长:

多年来,我们一直在各种命名空间中积累所有类型的东西。现在我们决定将一些命令放入其中,并将命名空间拆分为正确命名的命名空间;这样:

namespace util
{
uint32_t codecID( const char * name ) ;

void alignStrings( std::vector< std::string > * strings ) ;
}

应该成为

namespace codec
{

uint32_t codecID( const char * name ) ;

}

namespace fmt
{

void alignStrings( std::vector< std::string > * strings ) ;

}

只是为了增加乐趣,旧的命名空间是在几个包含文件中定义的。其中的所有内容都是内联/模板代码;所以没有与之相关的库。

显而易见的解决方案是将所有定义从旧命名空间复制到新命名空间,并将所有内容标记为已弃用的旧命名空间,逐项。

我们不能在不破坏多个项目的情况下重命名命名空间。

现在我想知道是否有更好的方法来做这样的事情,比如将namespace util的使用标记为已弃用。

我们使用gcc 4.7.3作为我们的生产编译器,但是对clang进行构建和测试以尝试捕获gcc细节;所以在任何这些编译器上工作都会有所帮助。

2 个答案:

答案 0 :(得分:2)

如果在新的头文件中定义新的命名空间,则可以使用#warning指令而不是逐项弃用旧的冗余头文件。 libstdc ++ does that。 Clang也支持该指令,但MSVC例如does not

答案 1 :(得分:0)

在C ++ 14中,我们允许将attributes应用于名称空间(尽管gcc似乎忽略了该属性)。这是通过defect report 1657产生的,具有CD4状态,这意味着它应适用于C ++ 14。

引入新措词的论文是N4196

  

但是,枚举数和名称空间均不允许使用属性。作为回应,CWG第1657期和EWG第113期被提交并受到好评。本文提出了通过允许在枚举器和名称空间上指定属性来解决这些问题的方法,并按照原先的意图将[[deprecated]]属性扩展到适用于这些实体。

a live godbolt example中查看它:

namespace [[deprecated]] util {

在clang中,如果我们使用codecID,则会看到以下警告:

warning: 'util' is deprecated [-Wdeprecated-declarations]
util::codecID( "hello") ;
    ^
note: 'util' has been explicitly marked deprecated here
namespace [[deprecated]] util
        ^

尽管clang警告说这是C ++ 17功能(我相信这是一个错误),但gcc警告说尽管it supports for it as a C++17 feature,该属性仍被忽略。