如何打印功能测试宏

问题描述 投票:0回答:1

C++20 引入了预定义功能测试宏的概念,允许检查语言和库功能的可用性(请参阅 https://en.cppreference.com/w/cpp/feature_test 中的表格)。

我正在编写一个简单的应用程序,它将打印其中一些宏的值。为了减少代码重复,我将打印提取到类似函数的宏中:

#include <iostream>

#define print(feature) std::cout << #feature " : " << feature << '\n'

int main()
{
    print(__cpp_aggregate_bases);
    print(__cpp_aggregate_nsdmi);
    print(__cpp_aggregate_paren_init);
}

然而事实证明,一些宏没有在我的编译器(g++ 11.4.0)中定义,例如

__cpp_auto_cast
__cpp_char
,编译失败。

是否有一种优雅的方法来检测未定义的宏(最好在

print
宏内部),而不必求助于这样的怪物:

#if defined(__cpp_auto_cast)
std::cout << "__cpp_auto_cast : " << __cpp_auto_cast << '\n';
#else
std::cout << "__cpp_auto_cast : undefined\n;
#endif

对每个功能测试宏都重复?

c++ macros c-preprocessor c++20
1个回答
0
投票

值得解释一下 cppreference 在这里使用的技巧。

考虑:

#define ONCE(x) #x

#define TWICE2(x) #x
#define TWICE(x) TWICE2(x)

并采用一些为最新 gcc 定义的 C++20 宏,

__cpp_using_enum
,以及另一个甚至不存在的宏,
__cpp_no_dangling

__cpp_using_enum
__cpp_no_dangling
ONCE
"__cpp_using_enum"
"__cpp_no_dangling"
TWICE
"201907L"
"__cpp_no_dangling"

所以

ONCE
是没用的,但是
TWICE
让我们处于一种可以区分存在和不存在的境地,并做一些有趣的事情。如果
TWICE(x)
给出一个以
_
开头的字符串,则为其指定值
0
。否则,手动计算该值 - 在这里我们可以相信它总是
YYYYMM

这就是 cppreference 宏的作用在示例中

// Expect a string that starts with 6-decimal-digits or with '_' (if unsupported)
#define COMPILER_VALUE_INT(n) #n [0] == '_' ? 0 : \
    (#n[5] - '0') + (#n[4] - '0') * 10 + (#n[3] - '0') * 100 + \
    (#n[2] - '0') * 1000 + (#n[1] - '0') * 10000 + (#n[0] - '0') * 100000
#define COMPILER_FEATURE_ENTRY(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
© www.soinside.com 2019 - 2024. All rights reserved.