Ошибка времени компиляции при вызове заданной перегрузки функции constexpr - PullRequest
0 голосов
/ 19 февраля 2019

Я пишу пользовательский шаблон переменной, который выполняет поиск в карте времени компиляции.

Проблема в том, что я хочу, чтобы ошибка времени компиляции возникала каждый раз, когда значение не найдено в этой карте - желательно с описательнойсообщение об ошибке.

пример кода:

template<key_t k, class pair, class... pairs>
static constexpr value_t get_local(std::tuple<pair, pairs...>)
{
    return (pair::key == k) ? pair::value : get_local<k>(std::tuple<pairs...>{});
}

template<key_t k> static constexpr value_t get_local(std::tuple<>)
{
    // Trigger error!
}

Я могу оставить get_local неопределенным во второй части кода, и это фактически вызывает ошибку компоновщика, но это не относится к категории«Описательное сообщение об ошибке».

Статические утверждения, я полагаю, здесь были бы бесполезны.

Я использую C ++ 17

1 Ответ

0 голосов
/ 19 февраля 2019

И немедленное падение в решении до delete перегрузки:

template<key_t k> static constexpr value_t get_local(std::tuple<>) = delete;

Это даст описательное сообщение несколько , которое мы пытаемся использовать в базовом случае, который неСуществуют.

В качестве альтернативы, со статическими утверждениями на месте:

template<key_t k> struct always_false { static constexpr bool value = false; };

template<key_t k> static constexpr value_t get_local(std::tuple<>)
{
    static_assert(always_false<k>::value, "Hit bad case!");
    return std::declval<value_t>();
}

Утилита always_false необходима для того, чтобы сделать условие утверждения зависимым, чтобы шаблон не был некорректным;Диагностика не требуется, поскольку static_assert(false, ...) сделает это.

Имейте в виду, что вы сами создаете эту перегрузку в своем собственном условном операторе:

(pair::key == k) ? pair::value : get_local<k>(std::tuple<pairs...>{});

Когда вы ударите случай кортежа с одним элементом.Обе «ветви» условного выражения должны быть действительными.Лучше всего обрабатывать его условно с помощью if constepxr:

if constexpr (pair::key == k) return pair::value;
else                          return get_local<k>(std::tuple<pairs...>{});

Поскольку вы указали, что pair::key == k можно вычислять в константном выражении.

...