c++ - Use static_assert para verificar los tipos pasados a la macro
visual-studio-2010 g++ (4)
Desafortunadamente, me quedan varias macros de la versión original de mi biblioteca que emplea una C bastante loca. En particular, tengo una serie de macros que esperan que se les pasen ciertos tipos. ¿Es posible hacer algo en la línea de:
static_assert(decltype(retval) == bool);
¿Y cómo? ¿Hay alternativas inteligentes?
Sí, me doy cuenta de que las macros son malas. Soy consciente de que C ++ no es C, etc.
Actualización0
Aquí hay un código relacionado , y el archivo fuente . Las sugerencias son bienvenidas. La pregunta original sigue siendo la misma.
Encontré que este es el más limpio, usando la sugerencia de @ UncleBens :
#include <type_traits>
static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
La mayoría de las macros se pueden reemplazar con funciones y / o plantillas en línea. Como ejemplo de ello, la macro isnan
, demasiado ingeniosa para la verificación de isnan
es una plantilla en C ++ 0x. Oh, mal ejemplo, pero entiendes la idea.
Las excepciones principales a esa regla son las macros que esencialmente implementan funciones de lenguaje de nivel superior. Por ejemplo, manejo de excepciones más inteligente, o covarianza, o un conjunto de declaraciones parametrizado.
En algunos casos, las macros que no pueden ser razonables expresadas como funciones o plantillas en línea, pueden reemplazarse con un tipo de preprocesamiento más inteligente, a saber, la generación de código. Entonces tienes un script en algún lugar que genera el código necesario. Por ejemplo, es posible realizar clases de opciones en C ++ puro con macros y plantillas, pero es velloso y, como alternativa más fácil de asimilar y quizás más fácil de mantener, se puede usar un script que genere las clases necesarias, a un costo adicional. construir pasos y tratar con múltiples idiomas.
Salud y salud,
Parece que necesitas decltype
porque tienes una expresión, pero quieres verificar un tipo. Ya hay suficientes formas de hacerlo ahora (C ++ 03). Por ejemplo, para comprobar un bool
inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)
// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
Descargo de responsabilidad: Esta es una mala respuesta, definitivamente hay soluciones mucho mejores. Solo un ejemplo :)
Es probable que ya esté implementado, pero es trivial implementarlo usted mismo;
template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //
template <class T1, class T2>
AssertHasType(T2)
{
CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}
Para ser utilizado de esta manera:
AssertHasType<bool>(retval);
Alternativa (sugerida por GMan):
template <class T1, class T2> struct SameType
{
enum{value = false};
}
template <class T> struct SameType<T,T>
{
enum{value = true};
};
Para ser utilizado como
static_assert(SameType<decltype(retval), bool>::value);