【问题标题】: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;
            

            【讨论】:

              猜你喜欢
              • 2011-05-23
              • 2020-02-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-06
              • 2015-07-31
              相关资源
              最近更新 更多