【问题标题】:How to check type on compile time如何在编译时检查类型
【发布时间】:2012-06-10 10:33:41
【问题描述】:
我提供了使用浮点型或双精度型编译程序的选项,但有一个问题:我需要手动设置 GL_FLOAT 或 GL_DOUBLE,因为我不知道如何执行以下操作:
typedef float MYTYPE;
#if MYTYPE == float
#define GL_MYTYPE GL_FLOAT // used for vertex array parameters.
#else
#define GL_MYTYPE GL_DOUBLE
#endif
注意:我没有 C++11 或其他任何东西,只有好的旧 C++。
【问题讨论】:
标签:
c++
visual-c++
c-preprocessor
【解决方案1】:
在 C++11 中,您可以使用 std::conditional 和 std::is_same 作为:
#define GL_MYTYPE std::conditional \
< std::is_same<MYTYPE,float>::value, \
GL_FLOAT, \
GL_DOUBLE \
>::type
在 C++03 中,您可以自己实现这些功能:
template<bool B, class T, class F>
struct conditional { typedef T type; };
template<class T, class F>
struct conditional<false, T, F> { typedef F type; };
和
template<class T, class U>
struct is_same { static const bool value = false; };
template<class T>
struct is_same<T, T> { static const bool value = true; };
注意conditional 的实现取自site 本身。
【解决方案2】:
#defines 在编译器运行之前由预处理器处理。所以它看不到typedef。
【解决方案3】:
使用预处理器宏来更改 typedef 行的作用
#if defined(TYPE_IS_FLOAT)
typedef float MYTYPE;
#else
typedef double MYTYPE;
#end
然后使用你的构建系统适当地设置TYPE_IS_FLOAT(当然要给它一个更好的名字)。
或者将所有类似行为的代码包装在一个模板类中,并为此类型使用模板参数,然后使用当时合适的版本。
【解决方案4】:
你可以这样做:
#define MYFLOAT
#ifdef MYFLOAT
typedef float MYTYPE;
#define GL_MYTYPE GL_FLOAT // used for vertex array parameters.
#else
typedef double MYTYPE;
#define GL_MYTYPE GL_DOUBLE
#endif
如果要使用float,则需要定义MYFLOAT,或者省略它以使用double。
PS:请注意,这不是在编译时评估的,而是在预处理时评估的。
【解决方案5】:
您可以按如下方式使用#ifdef:
#ifdef DOUBLE
#define GL_MYTYPE GL_FLOAT
//or
typdef ...
#endif
#ifdef FLOAT
#define GL_MYTYPE GL_DOUBLE
//or
typdef ...
#endif
您必须使用 DOUBLE 或 FLOAT 作为定义的符号来编译代码。
【解决方案6】:
我认为Nawaz's answer 是几乎正确的。在GL_FLOAT 和GL_DOUBLE 之间进行选择的特殊情况下,不需要std::conditional。只需使用ternary if:
#define GL_MYTYPE std::is_same<MYTYPE,float>::value?GL_FLOAT:GL_DOUBLE
这是因为 GL_FLOAT 和 GL_DOUBLE 不是类型,而是文字 GLenum 值。所以GL_MYTYPE 也不应该是类型名,而是GLenum。所以我宁愿使用:
const GLenum GL_MYTYPE = std::is_same<MYTYPE,float>::value?GL_FLOAT:GL_DOUBLE;