Почему при оценке в constexpr оказывается недостижимый код?

Я ожидал, что компилятор разрешит недопустимые операторы или сообщения об ошибках в недостижимом коде, включающем constexpr, если:

#include <type_traits>
#include <iostream>

struct ret_t;
struct only_declared_t;

auto test = [](auto a) {
    if constexpr(std::is_invocable_r_v<ret_t, decltype(a), int>) {
        return a(42);
    } else {
        return 42;
    }

    // I expect to never reach that statement, but the compiler complains
    static_assert(false, "This code should never be reached."); 
    return only_declared{};
};

int main() {
    std::cerr << "Result is " << test(10) << "\n";
}

Было бы полезно любое объяснение / обходной путь


person Markus W.    schedule 15.09.2020    source источник
comment
Компилятор должен продолжать синтаксический анализ кода, хотя бы для того, чтобы узнать, где заканчивается функция.   -  person Guy Incognito    schedule 15.09.2020
comment
Что касается обходного пути: выбросить исключение вместо static_assert?   -  person freakish    schedule 15.09.2020
comment
вы можете поместить static_asserts почти где угодно, их не нужно запускать, чтобы вызвать ошибку   -  person 463035818_is_not_a_number    schedule 15.09.2020
comment
как обходной путь, просто удалить? Код после else недоступен   -  person 463035818_is_not_a_number    schedule 15.09.2020
comment
В основном это stackoverflow.com/questions/53818624/ - Но даже тогда вы не можете безоговорочно иметь ложное статическое утверждение stackoverflow.com/questions/53945490/ - Шаблоны не t макросы, они являются частью системы типов. И if constexpr не разрешает суп из токенов, у него все еще есть ограничения   -  person StoryTeller - Unslander Monica    schedule 15.09.2020
comment
Вы «ожидали, что компилятор разрешит недопустимые операторы или сообщения об ошибках в недоступном коде», почему? «Недостижимость» во время выполнения не означает, что компилятор не должен его компилировать, и, конечно же, не означает, что он не должен быть синтаксически или семантически правильным.   -  person user207421    schedule 15.09.2020


Ответы (1)


static_assert работает во время компиляции, поэтому он генерирует ошибки времени компиляции независимо от доступности кода. Вы можете использовать assert для проверок во время выполнения. assert не подлежат оценке.

person Michael Lukin    schedule 15.09.2020
comment
Это не имеет ничего общего с static_assert. Весь код компилируется независимо от доступности. - person user207421; 15.09.2020
comment
@MarquisofLorne, вы абсолютно правы. - person Michael Lukin; 15.09.2020
comment
На самом деле это ужасающе неверно. Пожалуйста, не пытайтесь угадать ответ, это вводит людей в заблуждение. - person Passer By; 15.09.2020
comment
Стандарт @PasserBy C ++ гласит: В объявлении static_assert константное выражение должно быть контекстно преобразованным константным выражением типа bool. Если значение выражения при таком преобразовании истинно, объявление не действует. В противном случае программа имеет неправильный формат, и результирующее диагностическое сообщение должно включать текст строкового литерала, если таковой имеется, за исключением того, что символы, не входящие в базовый исходный набор символов, не должны появляться в диагностическом сообщении. Что на самом деле не так? - person Michael Lukin; 15.09.2020
comment
Цитата в вашем комментарии прекрасна. С другой стороны, ваш ответ не совсем ясен. - person cigien; 15.09.2020