функция constexpr и ее параметр - PullRequest
0 голосов
/ 28 апреля 2018
constexpr int hello(int j) {
    return j * 12;
}

constexpr int bye(int j = 6) {
    return j * 12;
}

int main() {
    int i = 6;
    constexpr int a1 = hello(i); //error
    constexpr int a2 = hello(6); //ok
    constexpr int a3 = hello(int(6)); //ok
    constexpr int a4 = bye(); //ok
    constexpr int a5 = bye(i); //error
    constexpr int a6 = bye(6); //ok
    return 0;
}

Какая разница между hellow(i) и hello(6)? Я думаю, один - int j = i;, а j - не constexpr, а другой - int j = 6, а j - еще не constexpr, оба типа j int.
int * literal! = Constexpr , поэтому тип возвращаемого значения не является constexpr.

Я получил вышеуказанный вывод из примера в книге:
int staff_size = 27; //staff_size is not a const expression

Хотя staff_size инициализируется из литерала, он не является постоянным выражением потому что это обычный int, а не const int.

Более того, я замечаю, что hello(int(6)) тоже отлично работает, что здесь за «вещь»?

Кроме того, bye() работает, а hello(i) - нет, оба параметра инициализируются внутри функции, только один со значением по умолчанию, какой здесь смысл?

Очень растерялся, надеюсь, кто-нибудь сможет объяснить: D

PS: понятия не имею, чтобы придумать лучший заголовок, извините за это

Ответы [ 2 ]

0 голосов
/ 28 апреля 2018

Здесь следует отметить, что компилятор «проверяет» код, а не «читает» его.

Компилятор ожидает, что все части constexpr будут известной действительной константой во время компиляции. Таким образом, хотя мы с вами знаем, читая код, что значение i никогда не меняется, компилятор не «узнает» его, пока вы не объявите i как константу. Что касается этого, вы могли бы где-то выполнить другой код, чтобы изменить значение i.

Во всех случаях, когда функция вызывается без i, компилятор без сомнения знает, что значение j является постоянным целым числом со значением 6, (примечание : int(6) - это то же самое, что и 6).

0 голосов
/ 28 апреля 2018

Разница между hello(6) и hello(i) заключается в том, что 6 в hello(6) является функциональным параметром constexpr, а i в hello(i) является обычным параметром int.

Если вы объявите i как constexpr int i = 6;, тогда hello(i) скомпилирует и выполнит.

В hello(int(6)) вы говорите: 6, целочисленный литерал, в int. Это избыточная операция. hello(int(6)) и hello(6) будут иметь похожее, если не идентичное поведение.

bye() работает, поскольку параметр функции использует параметр по умолчанию (j = 6 в constexpr int bye(int j = 6);). Инициализированный по умолчанию параметр известен во время компиляции, таким образом, это constexpr по определению

...