默认值的函数模​​板

时间:2017-07-25 06:00:58

标签: c++

我这里有一些代码,它使用特殊值来检查变量是否已初始化。

#define NULLVALUE_FLOAT         -9999
#define NULLVALUE_INT           -9999
#define NULLVALUE_UINT          0
#define NULLVALUE_DOUBLE        -9999
#define NULLVALUE_LONG          -9999
#define NULLVALUE_LONGLONG      -9999
#define NULLVALUE_CSTRING       ""

bool isNull(float value) { return NULLVALUE_FLOAT == value; }
bool isNull(double value); ...
bool isNull(long value);...
bool isNull(int value);...
bool isNull(UINT value);...
bool isNull(CString value);...

因此无符号的特殊值为零,有符号整数和浮点数为-9999,字符串为空字符串。

现在我想将其重写为一个模板函数,但由于CString版本而出现问题。我能做的最好的是两个函数,一个用于基本类型,一个用于CString。

template<typename T,
    bool E = std::is_fundamental<T>::value && !std::is_unsigned<T>::value && (std::is_floating_point<T>::value || std::is_integral<T>::value),
    bool E2 = std::is_fundamental<T>::value && std::is_unsigned<T>::value>
bool isNull(const T &t) 
{ 
    if (E)
        return t == -9999;
    else if (E2)
        return t == 0;
    else
        return false;
}

bool isNull(const CString &  s)
{
    return s == "";
}

是否可以仅使用一个函数实现此功能,即使添加其他具有默认值的类也是如此?

2 个答案:

答案 0 :(得分:5)

如果您将注意力从定义函数转移到定义命名Null值的方式,解决方案就会非常容易。

添加一个公开value成员的特征类。专门然而你觉得方便。

template<typename T, typename = void>
struct NullValueHolder{};

template<typename T>
constexpr decltype(NullValueHolder<T>::value) NullValue = NullValueHolder<T>::value;  
// Utility for easy referral 

template<typename T>
struct NullValueHolder<T, std::enable_if_t<std::is_arithmetic<T>::value && std::is_signed<T>::value>> {
  static constexpr T value = -9999;
};

template<typename T>
struct NullValueHolder<T, std::enable_if_t<std::is_unsigned<T>::value>> {
  static constexpr T value = 0;
};

template<>
struct NullValueHolder<CString, void> {
  static constexpr const char * value = "";
};

以上大量使用SFINAE。主模板中的void必须与专业化匹配才能选择该专业化。如果符合条件,则每个enable_if_t都会提供void

现在该函数自行编写:

template<typename T>
bool isNull(T const& t) { return t == NullValue<T>; }

答案 1 :(得分:0)

现在,C ++ 17已经出现在visual studio中,这可以通过“if constexpr”功能轻松解决。让编译器根据需要生成函数。

android:duplicateParentState="true"