我试图使用C++17if constexpr
进行条件编译,但它的行为并不符合我所期望的方式。
例如,对于下面的代码,C++仍然编译由宏x2
定义的代码,
#include <string>
#include <iostream>
#include <type_traits>
#define X1 pp("x")
#define X2 pp("x", "x")
void pp(const std::string str){
std::cout << str << std::endl;
}
int main(){
std::map<std::string, int> map;
if constexpr (std::is_null_pointer_v<decltype(map)>)
X2;
else
X1;
}
并吐出以下错误消息:
1.c:6:23: error: too many arguments to function ‘void pp(std::__cxx11::string)’
#define X2 pp("x", "x")
^
1.c:18:3: note: in expansion of macro ‘X2’
X2;
^~
知道如何跳过X2的编译吗?
谢啦!
这在模板之外是不可能的! 来自CPPreference.com
在模板之外,完全检查丢弃的语句。 如果constexpr不是#if
预处理指令的替代品:
void f() {
if constexpr(false) {
int i = 0;
int *p = i; // Error even though in discarded statement
}
}
知道如何跳过X2的编译吗?
一种选择是为此提供一个模板函数。
template<typename T>
void test()
{
if constexpr (std::is_null_pointer_v<T>)
X2;
else
X1;
}
int main()
{
std::map<std::string, int> map;
test<decltype(map)>(); // now chooses the X1
}
在模板之外,如果ConstExpr被完全检查,则即使的false分支也是如此。 要做您想做的事情,您需要使用
#if
预处理器指令,或者将if constexpr
代码放入模板中。