Подтвердить что ты не робот

Как избежать предупреждения о возврате выражения при использовании static_assert?

У меня есть две библиотеки, с которыми я работаю, и для удобства я написал конвертер между некоторыми типами/структурами, которые они используют.

template<typename T>
struct unsupportedType : std::false_type
{};

template<typename T>
FormatB getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}

template<>
FormatB getFormat<FormatA::type1>()
{
    return FormatB(//some parameters);
}

template<>
FormatB getFormat<FormatA::type2>()
{
    return FormatB(//some other parameters);
}

Теперь из-за структуры unsupportedType компилятор не сразу видит, что утверждение всегда терпит неудачу и, таким образом, не вызывает ошибку компиляции, если не-специализированная версия не называется где-то. Однако компилятор также не знает, что оператор return после static_assert не нужен. Я не просто хочу разместить произвольное выражение return после утверждения, чтобы избавиться от предупреждения.

Вопрос: Что такое чистый способ избавиться от предупреждения?

4b9b3361

Ответ 1

Я попытался бы избежать static_assert, используя что-то вроде

template<typename T> FormatB getFormat()=delete;

Затем авторы компилятора могут улучшить эти сообщения об ошибках.

Ответ 2

Существует более одного способа выхода из функции, return ing - один, но throw ing - это другое:

template<typename T>
FormatB getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
    throw 0; // Unreachable
}

Ответ 3

Как вы сказали в комментарии к принятому ответу, что он фактически не отвечает на вопрос напрямую, вот рабочее решение, которое может помочь будущим читателям.


Чтобы решить эту проблему, вы можете просто определить свой шаблон функции следующим образом:

template<typename T, typename R = void>
R getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}

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


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

#include<type_traits>

template<typename T>
struct unsupportedType : std::false_type
{};

struct FormatA{
    using type1 = int;
    using type2 = char;
};

struct FormatB{};

template<typename T, typename R = void>
R getFormat()
{
    static_assert(
        unsupportedType<T>::value, "This is not supported!");
}

template<>
FormatB getFormat<FormatA::type1>()
{
    return FormatB();
}

template<>
FormatB getFormat<FormatA::type2>()
{
    return FormatB();
}

int main() {}

Ответ 4

Вы можете использовать GCC __builtin_unreachable (это путь вниз по этой ссылке), чтобы сообщить компилятору, что данная строка недоступна, который будет подавлять это предупреждение. (В основном я упоминаю это для C-разработчиков, которые здесь, для С++, метод, использующий delete выше, лучше).