使用constexpr和lambda时出现编译器错误

Compiler error when using constexpr and lambda

本文关键字:编译器 错误 constexpr lambda 使用      更新时间:2023-10-16

我在将constexpr函数与lambdas一起使用时遇到了一个问题。以下代码是再现错误的最小版本:

#include <iostream>
constexpr unsigned bar(unsigned q) {
    return q;
}
template<unsigned N>
unsigned foo() {
    return N;
}
template<typename F>
void print(F f) {
    std::cout << f() << std::endl;
}
template<unsigned Q>
int stuff() {
    constexpr unsigned n = bar(Q);
    print([]() { return foo<n>(); });
}
int main() {
    stuff<13>();
}

使用gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)编译时,存在以下编译器错误:

constexpr_template.cpp: In lambda function:
constexpr_template.cpp:24:9:   instantiated from ‘stuff() [with unsigned int Q = 13u]::<lambda()>’
constexpr_template.cpp:24:2:   instantiated from ‘int stuff() [with unsigned int Q = 13u]’
constexpr_template.cpp:29:12:   instantiated from here
constexpr_template.cpp:24:32: error: no matching function for call to ‘foo()’
constexpr_template.cpp:24:32: note: candidate is:
constexpr_template.cpp:9:10: note: template<unsigned int N> unsigned int foo()

现在奇怪的是,如果将constexpr unsigned n = bar(Q);更改为constexpr unsigned n = Q;,它就会起作用。同样起作用的是print([]() { return foo<bar(Q)>(); });。。。

这是GCC中的错误还是我做错了什么?

Gcc 4.6是第一个支持constexpr的版本,在发布这些功能时出现小错误并不罕见。您可以从Coliru上的这个Live示例中验证gcc 4.8.1和Clang 3.4 SVN是否正确解析了您的代码。您可能应该相应地升级编译器。