c++ - significado - ¿Cómo evitar la advertencia de que no hay expresión de retorno cuando se usa static_assert?
por ahi o por hay (4)
Hay más de una forma de salir de una función, return
es una, pero throw
es otra:
template<typename T>
FormatB getFormat()
{
static_assert(
unsupportedType<T>::value, "This is not supported!");
throw 0; // Unreachable
}
Tengo dos bibliotecas con las que trabajo y escribí un convertidor entre algunos de los tipos / estructuras que usan, para mayor comodidad.
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);
}
Ahora, debido a la estructura unsupportedType, el compilador no ve inmediatamente que la aserción siempre fallará y, por lo tanto, no arroja un error de compilación si la versión no especializada no se llama en alguna parte. Sin embargo, el compilador tampoco sabe que una declaración de retorno después del static_assert
es innecesaria. No solo quiero colocar una declaración de devolución arbitraria después de la afirmación para deshacerme de la advertencia.
Pregunta: ¿Cuál es una forma limpia de deshacerse de la advertencia?
Intentaría evitar el static_assert, usando algo como
template<typename T> FormatB getFormat()=delete;
Los escritores del compilador pueden entonces trabajar para mejorar esos mensajes de error.
Puede usar __builtin_unreachable
de GCC (está muy abajo en ese enlace) para comunicarle al compilador que una línea determinada no está disponible, lo que suprimirá esa advertencia. (Principalmente menciono esto para C desarrolladores que terminan aquí; para C ++, el método que usa delete
arriba es mejor).
Para usted dijo en un comentario a la respuesta aceptada que en realidad no responde la pregunta directamente , aquí hay una solución de trabajo que puede ser de ayuda para los lectores futuros.
Para resolver el problema , puede definir su plantilla de función como sigue:
template<typename T, typename R = void>
R getFormat()
{
static_assert(
unsupportedType<T>::value, "This is not supported!");
}
No se requieren cambios para las otras especializaciones, el tipo R
se puede deducir directamente del tipo de devolución.
Sigue un ejemplo de trabajo mínimo que muestra cómo funciona:
#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() {}