1 Востаннє редагувалося wander (07.12.2019 23:45:38)

Тема: Function overloading and consteval [C++20]

Дивлюся я такий на C++ 20 фічі додані в Core і помітив такі штуки, як consteval та std::is_constant_evaluated, і щось це у мене викликає дисонанс.
Тобто можна писати так:

constexpr int foo(int a, int b) {
    if (std::is_constant_evaluated()) { /* make some compile-time stuff */ }
    else { /* make some run-time stuff */ }
}

І якось дивно це виглядає, по-перше, чому if не constexpr?
По-друге, є ж тепер consteval чому б не дозволити робити перевантаження через нього?
Можна було б тоді писати так:

consteval int foo(int a, int b) { /* make some compile-time stuff */ }
          int foo(int a, int b) { /* make some run-time stuff */ }

int main() {
    foo(1, 2); // Буде вирахувано в compile-time
    foo(x, y); // Буде вирахувано в run-time
}

Вони ж вміють через constexpr визначати коли функція compile-time.
І по-третє, if constexpr повинен був стати тоді if consteval за логікою?

Подякували: leofun011

2 Востаннє редагувалося wander (18.02.2020 17:00:29)

Re: Function overloading and consteval [C++20]

Ну, гаразд, чому if не constexpr можна здогадатися, але що if тепер розумний якийсь?

3

Re: Function overloading and consteval [C++20]

Чомусь сміюсь, ось, майже через два роки нарід зі стандартизації теж помітив проблему, описану (частково) в цьому треді. Виявляється, що якщо в контексті if (std::is_constant_evaluated()) викликати іншу consteval ф-ю, то це не спрацює, бо це ill-formed.

consteval int f(int i) { return i; }

constexpr int g(int i) {
    if (std::is_constant_evaluated()) { /* make some compile-time stuff */
        return f(i) + 1; // <== ill-formed
    } else { /* make some run-time stuff */
        return 42;
    }
}

І це все частково через constexpr/consteval та намаганням в магію зі звичайним if. Проблема полягає в тому, що виклик ф-ї f() в g() вимагає immediate invocation і повинен бути constant expression, чим він не є, в цьому випадку. Здавалось би, чому б тоді не взяти просто if constexpr, але i в цьому випадку магії не відбудеться, бо тоді if constexpr (std::is_constant_evaluated()) буде завжди true. Тому вирішили додати ще й if consteval...
І тепер можна писати так:

constexpr int g(int i) {
    if consteval { /* make some compile-time stuff */ }
    else { /* make some run-time stuff */ }
}

:D

Подякували: koala, leofun01, Arete3