提问者:小点点

如果constexpr失败,为什么C++17的这种用法?


我试图使用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的编译吗?

谢啦!


共2个答案

匿名用户

这在模板之外是不可能的! 来自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代码放入模板中。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(constexpr|失败|c++17|用法)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?