Рассмотрим следующий пример: constexprПочему я не могу разрешить постоянное выражение после увеличения -fconstexpr-шагов?
#include <iostream>
constexpr int fib(const int i)
{
if (i == 0) return 0;
if (i == 1) return 1;
return fib(i-1) + fib(i-2);
}
int main(){
std::cout << fib(45) << '\n';
}
Несмотря на constexpr, это не оценивается во время компиляции.
Хитрости я научился применять оценку времени компиляции, нижеследовал:
#include <iostream>
#include <type_traits>
#define COMPILATION_EVAL(e) (std::integral_constant<decltype(e), e>::value)
constexpr int fib(const int i)
{
if (i == 0) return 0;
if (i == 1) return 1;
return fib(i-1) + fib(i-2);
}
int main(){
std::cout << COMPILATION_EVAL(fib(45)) << '\n';
}
Это работает, г ++, однако я получаю следующее сообщение об ошибке в звоне ++:
clang++-3.9 --std=c++1z -o main main.cpp
main.cpp:14:33: error: non-type template argument is not a constant expression
std::cout << COMPILATION_EVAL(fib(45)) << '\n';
^~~~~~~
main.cpp:4:66: note: expanded from macro 'COMPILATION_EVAL'
#define COMPILATION_EVAL(e) (std::integral_constant<decltype(e), e>::value)
^
main.cpp:9:3: note: constexpr evaluation hit maximum step limit; possible infinite loop?
if (i == 1) return 1;
^
main.cpp:10:21: note: in call to 'fib(7)'
return fib(i-1) + fib(i-2);
^
main.cpp:10:21: note: in call to 'fib(9)'
main.cpp:10:10: note: in call to 'fib(11)'
return fib(i-1) + fib(i-2);
^
main.cpp:10:10: note: in call to 'fib(12)'
main.cpp:10:10: note: in call to 'fib(13)'
main.cpp:10:21: note: (skipping 23 calls in backtrace; use -fconstexpr-backtrace-limit=0 to see all)
return fib(i-1) + fib(i-2);
^
main.cpp:10:10: note: in call to 'fib(41)'
return fib(i-1) + fib(i-2);
^
main.cpp:10:10: note: in call to 'fib(42)'
main.cpp:10:10: note: in call to 'fib(43)'
main.cpp:10:10: note: in call to 'fib(44)'
main.cpp:14:33: note: in call to 'fib(45)'
std::cout << COMPILATION_EVAL(fib(45)) << '\n';
^
1 error generated.
Я попытался увеличение constexpr-шагов, но лязг все еще не будет компилировать код:
clang++-3.9 -fconstexpr-depth=99999999 -fconstexpr-backtrace-limit=9999999 -fconstexpr-steps=99999999 --std=c++1z -o main main.cpp
Что я должен сделать для лязга, чтобы скомпилировать этот код, как это?
лязг ++:
clang version 3.9.0-svn267343-1~exp1 (trunk)
г ++:
g++ (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0
Я думаю, что глубина важна. Является ли 'std :: array arr;' работает также? fib (45) занимает около 6 секунд для работы на моей машине. Это не оценивается во время компиляции. –
Я отправил ответ о возможной проблеме, но я думаю, что это может быть ошибка в clang. См. [Constexpr depth limit с clang (fconstexpr-depth не работает)] (https://stackoverflow.com/questions/24591466/constexpr-depth-limit-with-clang-fconstexpr-depth-doesnt-seem-to- работа) –
@sleeptightpupper Я не вижу ошибки. Возможно, отсутствует функция (для memoize 'constexpr'). –