【问题标题】:Compile time type checking with branching logic使用分支逻辑进行编译时间类型检查
【发布时间】:2015-02-19 19:30:13
【问题描述】:

我正在尝试确定是否有办法在编译时同时对两种不同类型进行条件检查。

例子:

template <typename T>
class MyClass
{
    returnVal myFunction() const
    {
        // Is there a compile time way of doing this?  std::conditional?
        return myConditionFunction(std::is_same<char, T> || std::is_same<unsigned char, T>);
    }

    returnVal myConditionFunction(std::true_type& const) const
    {
        // perform calculations on char or unsigned char
    }

    returnVal myConditionFunction(std::false_type& const) const
    {
        // perform calculations on non-char/unsigned char types
    }
};

如果类型是 char 或 unsigned char,我想调用一个函数。

编辑:更新代码以显示我正在使用模板类。

【问题讨论】:

  • 你目前所做的已经是编译时的事情了。
  • 但是 (std::is_same || std::is_same) 不起作用。我可以做一个或另一个,但不能同时做。
  • 你擅长的 char 和 unsigned char 的模板怎么样?

标签: c++ c++11 stl compile-time


【解决方案1】:

您可以使用条件生成编译时间常数,并创建一个匹配true_typefalse_type 的类型:

returnVal myFunction() const
{
   typedef std::integral_constant<bool, 
                                  std::is_same<unsigned char, T>::value
                               || std::is_same<         char, T>::value> selector;

   return myConditionFunction(selector());
}

请注意,std::true_type 只是 std::integral_constant&lt;bool,true&gt;std::false_type 也是如此。

【讨论】:

    【解决方案2】:

    有很多方法可以做你想做的事。如果您不想自己编写任何新模板,则可以执行以下操作(伪代码,因为未指定 returnVal,并且未指定或从任何地方推断出 T):

    #include <type_traits>
    
    returnVal myFunction() const
    {
        return myConditionFunction(
            typename std::is_same<unsigned char, typename std::make_unsigned<T>::type>::type());
    }
    
    returnVal myConditionFunction(std::true_type& const) const
    {
    }
    
    returnVal myConditionFunction(std::false_type& const) const
    {
    }
    

    这使用类型特征库中的std::make_unsigned 元函数将T 转换为无符号对应项(因此,如果Tcharunsigned charstd::make_unsigned&lt;T&gt;::type 将是unsigned char )。然后,std::is_same 的结果用于分派到适当的函数实现。

    或者,您可以编写自己的特征:

    template <typename T>
    struct is_char_or_uchar 
    { 
        typedef false_type type; 
        static const bool value = false;
    }
    
    template<>
    struct is_char_or_uchar<char>
    {
        typedef true_type type;
        static const bool value = true;
    }
    
    template<>
    struct is_char_or_uchar<signed char>
    {
        typedef true_type type;
        static const bool value = true;
    }
    
    template<>
    struct is_char_or_uchar<unsigned char>
    {
        typedef true_type type;
        static const bool value = true;
    }
    

    并像这样使用它:

    returnVal myFunction() const
    {
        return myConditionFunction(typename is_char_or_uchar<T>::type());
    }
    
    returnVal myConditionFunction(std::true_type& const) const
    {
    }
    
    returnVal myConditionFunction(std::false_type& const) const
    {
    }
    

    或者,如果您有 Boost,则可以使用 boost::mpl::or_ 和两次对 std::is_same 的调用。

    【讨论】:

    • 快速尝试第一个选项,我在使用模板时遇到编译错误,在使用 std::make_unsigned() 之前我需要保证类型 T 不是布尔值。
    猜你喜欢
    • 2020-02-07
    • 2011-05-23
    • 2022-10-06
    • 2017-09-25
    • 1970-01-01
    • 2018-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多