我有以下代码片段:
#include <iostream>
// Another function that takes a const char array reference
template <size_t N>
constexpr
int anotherFunction(const char (&str)[N]) {
int ct = 0;
for(int i=0; i< N; i++)
{
ct++;
}
return ct;
}
#define WRAP(sev, str, ...) do { constexpr int ans = anotherFunction(str); std::cout << ans << std::endl;} while(0);
// Function template that takes a string literal and passes it to another function
template <size_t N, typename... Args>
void printString(const int& log, const char (&str)[N], Args&&... args) {
WRAP(0, str, std::forward<Args>(args)...);
}
int main() {
printString(0, "Hello, World! %s %d", 1, "hello");
return 0;
}
在 gcc 9 之前编译都很好,但从 gcc 10 开始会出现以下错误:
:25:53:从这里需要 :15:48: 错误:'str' 不是常量表达式 15 | 15 #define WRAP(sev, str, ...) do { constexpr int ans = anotherFunction(str); std::cout :19:5:注意:在宏“WRAP”的扩展中 19 | 19 WRAP(0, str, std::forward(args)...); | ^~~~ 编译器返回:1对应的godbolt链接是: https://godbolt.org/z/zn1a45qMY
我试图通过阅读变更日志来了解引入了哪些更改,但还无法理解它。上面的内容本质上模仿了我一直试图将其封装到我的项目中的方法中的第三方宏。这里出了什么问题?
函数参数永远不能在常量表达式中使用。
您试图将
ans
的初始化强制为依赖于 str
的常量表达式,但 str
是一个函数参数,没有固定的编译时已知值。它的值取决于函数的调用位置。
旧的 GCC 行为是一个错误。
但是你的代码无论如何都不需要
constexpr
。只需将其删除即可。您不会尝试在编译时在常量表达式中使用 ans
。