2015-09-16 3 views
4

Итак, начиная с C++ 14, ограничения, которые constexpr имели на C++ 11, исчезли, например, с новыми переменными или петлями в функции constexpr.«constexpr» в C++ 14

И последние версии компиляторов GCC и Clang уже поддерживают их.

Итак, проблема в этом ... Функция constexpr вычисляется во время компиляции, а не во время выполнения, если значение, переданное ему как параметр, является константой. Итак, результат функции, которую я написал ниже, должен появляться мгновенно во время выполнения, правильно? Но это не так.

Мой вопрос: почему это происходит? И есть ли у меня неправильное понимание функции constexpr C++ 14? Спасибо.

EDIT: Да, я использовал -OO, поэтому он не сработает. Но настройка -O1 или более высокая скорость оптимизации делает трюк, и программа выполняется, как ожидалось. Спасибо всем за ваши ответы.

#include <iostream> 
#include <chrono> 

constexpr long long addition(long long num) 
{ 
    long long sum = 0; 
    for (int i = 0; i <= num; i++) 
    { 
     sum += i; 
    } 

    return sum; 
} 

int main() 
{ 
    auto start = std::chrono::steady_clock::now(); 
    ////////////////////////////////////////////// 

    std::cout << addition(500000000); //500 mill //executes in 1.957 seconds 

    /////////////////////////////////////////////// 
    auto stop = std::chrono::steady_clock::now(); 
    auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start); 
    std::cout << "\n\nIt took " << static_cast<double>(dur.count())/1000 << " seconds!"; 

    std::cin.get(); 
} 
+3

Функция constexpr * может быть * вычислена во время компиляции, компилятору не обязательно. Вы используете '-O3'? –

+1

gcc с '-O2' или выше заменяет вызов константой, [см. Здесь] (http://goo.gl/O5jaIY) –

+1

также предлагает' auto x = дополнение (500000000); 'и оставить cout'ing после остановки хронометра –

ответ

9

Функция constexpr вычисляется во время компиляции, а не во время выполнения, до тех пор, как значение передается к нему в качестве параметра является константой.

Нет, компилятор может сделать это по своему усмотрению, так же как и с «чистой» функцией, которая не является constexpr. Если вы не используете его в контексте, где требуется постоянная времени компиляции, такая как инициализация переменной constexpr или использование в привязке к массиву (будьте осторожны с расширением VLA g ++) или как аргумент шаблона непигового типа. Для этих случаев требуется оценка времени компиляции. (Это не исчерпывающий список: существуют другие контексты, для которых требуются постоянные времени компиляции, такие как метки ярлыка коммутатора, но как вы отправляете значение метки метки в cout?)

0

Чтобы добавить к ответу @Ben Voigt, вот фактический рабочий пример, который работает в кратчайшие сроки:

#include <iostream> 
#include <chrono> 

constexpr long long addition(long long num) 
{ 
    long long sum = 0; 
    for (int i = 0; i <= num; i++) 
    { 
     sum += i; 
    } 

    return sum; 
} 

int main() 
{ 
    auto start = std::chrono::steady_clock::now(); 
    ////////////////////////////////////////////// 

    constexpr auto res = addition(500000); 
    std::cout << res; //500 mill //executes in 0 seconds 

    /////////////////////////////////////////////// 
    auto stop = std::chrono::steady_clock::now(); 
    auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start); 
    std::cout << "\n\nIt took " << static_cast<double>(dur.count())/1000 << " seconds!"; 

    std::cin.get(); 
} 

Live Example. Обратите внимание, что мне пришлось сбрить несколько 0 с вашего размера ввода. Вы можете настроить его с помощью опции компилятора -fconstexpr-steps=N (для Clang).

Смежные вопросы