使用 constexpr 替换 #define 和 #ifdef 进行条件编译



我正在尝试替换预处理器 #define 和 #if/#ifdef,我用它来控制带有constexpr变量和ifs的条件编译。

是否可以声明 constexpr 变量,以便它们在不分配运行时存储的情况下重现 #defines,并且获取一个地址会导致编译时错误?

编辑以添加代码示例。

所以在标题中,我想有类似的东西

namespace ExampleNamespace
{
enum class Platform : int {Darwin, Linux, Windows};
constexpr Platform BuildPlatform = Platform::Darwin;  // Line A.
};

在我想要的代码中

if constexpr (Platform::Darwin == BuildPlatform)        // Line B.
{
cout << "Platform is Darwin" << endl;
}
else
{
cout << "Platform is not Darwin" << endl;
};
const Platform *const PlatformAddress = &BuildPlatform; // Line C.
const Platform &BuildPlatform2 = BuildPlatform;         // Line D.

然后目标是更改 A 行上 BuildPlatform 的定义,使得 B 行在编译时被计算(else 子句被丢弃/未编译(,而 C 行和 D(以及任何做同样事情的东西,或者依赖于 BuildPlatform 的运行时存储(都会生成编译器错误。

在 C++17 中这样的结构可能吗?

部分可能:

if constexpr (Platform::Darwin == BuildPlatform) {        // Line B.
std::cout << "Platform is Darwin" << std::endl;
} else {
std::cout << "Platform is not Darwin" << std::endl;
}

template <typename T> void foo() {static_assert(false);}是畸形的, 所有分支的代码都应该具有某种有效性。

#ifdef (DarwinPlatform) // constexpr cannot be used here, you have to 
//rely on MACRO here
# include <darwin.h>     // Some OS specific header
#endif
void foo()
{
if constexpr (Platform::Darwin == BuildPlatform) {
DarwinMethod(); // Won't compile on other platforms as
// the method doesn't exist.
// you should make the block template with template dependent code
// to allow code to compile.
// as http://coliru.stacked-crooked.com/a/c695575e4dcdecee
}
}

也许你可以使用它。

enum class Platform { Darwin, Linux, Windows };
#ifdef __darwin__
constexpr Platform  BuildPlatform = Platform::Darwin;
#elif __linux__
constexpr Platform  BuildPlatform = Platform::Linux;
#elif __WIN32
constexpr Platform  BuildPlatform = Platform::Windows;
#endif
// your code then uses it like this
if constexpr (BuildPlatform == Platform::Darwin) 
{         
}
else if constexpr (BuildPlatform == Platform::Linux)
{
}
else if constexpr (BuildPlatform == Platform::Windows)
{   
}

对于标志和整数,枚举值有效。

对于浮点值,没有保证不使用 ODR 的 constexpr 方法。 ODR 使用往往会导致为常量创建存储。

您可以使用返回浮点值的 constexpr 函数,但该函数很容易占用存储。

最新更新