有没有办法创建具有通用属性的命名空间?

时间:2017-03-05 21:27:03

标签: c++ c++14

我知道下面的源代码不是有效的C ++代码,只是为了说明我的问题:

#include <iostream>

namespace mylib {
    using deprecated = [[deprecated]];
}

[[mylib::deprecated]] void deprecated_function() {
    std::cout << "Calling deprecated function!" << std::endl;
}

int main(void) {
    deprecated_function();
    return 0;
}

有没有办法实现这样的事情?目的是删除#define并独占使用属性说明符 - 排除编译器保护和验证,因为这肯定需要一定程度的预处理 - 熟练程度:)(但是,predef is your friend )。

例如:

// mylib-config.hpp
namespace mylib {
    #if __cplusplus > 201402L // C++17 has support for [[deprecated]]
        using deprecated = [[deprecated]]

    #elif defined(__clang)
        using deprecated = [[clang::deprecated]]

    #elif defined(__GNUC__)
        using deprecated = [[gnu::deprecated]]

    #else // What to do? Is there a placeholder?
        // Starting C++17, this invalid attribute should be ignored.
        // Before that, the result is implementation-defined.
        // (Is there any chance for undefined behaviour in this case?)
        using deprecated = [[completely_invalid_identifier__]];
    #endif
}

// mylib.hpp
[[mylib::deprecated]] void deprecated_function();

我目前的解决方案是使用属性所在的#define,例如:

// mylib-config.hpp
#if __cplusplus > 201402L
    #define mylib_DEPRECATED [[deprecated]]

#elif defined(__clang)
    #define mylib_DEPRECATED [[clang::deprecated]]

#elif defined(__GNUC__)
    #define mylib_DEPRECATED [[gnu::deprecated]]

#else
    #define mylib_DEPRECATED
#endif

// mylib.hpp
mylib_DEPRECATED void deprecated_function();

如果确实可以将您的应用程序在您自己的命名空间中使用的所有属性规范化,那么您如何解释某些编译器上缺少特定属性? (例如,仅适用于GCC但在其他工具链上不需要的属性)。

1 个答案:

答案 0 :(得分:3)

不,您不能将属性放在命名空间中,也不能将它们与命名空间相关联。只需定义一个宏。将定义放在标题中,以便不同的编译器可以选择不同的,合适的标题版本。