有没有一种方法可以创建具有广义属性的命名空间?

4

我知道下面这段源代码并不是有效的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是你的朋友)。
例如:
// 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个回答

3

不能将属性放在命名空间中,也不能将其与命名空间关联。只需定义一个宏即可。将定义放在头文件中,以便不同的编译器选择不同的适用版本。


1
这正是我现在正在应用的解决方案,我只是想知道是否有任何标准可以让我对属性进行上下文化。如果是这样,我认为属性说明符与当前依赖于编译器的属性相比目前没有真正的改进(或者至少要等到大多数编译器都有良好的 C++17 支持,其中未知属性只是被忽略)。顺便问一下,你认为委员会是否有可能添加“用户命名空间”属性说明符? - Flávio Lisbôa
@FlávioLisbôa:我不知道,但可以看一下(https://isocpp.org/forums)。也许可以在其中一个列出的群组中提问。 - Cheers and hth. - Alf

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