2017-07-25 71 views
0

我在这里有一些代码,它使用特殊值来检查变量是否被初始化。默认值的函数模​​板

#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);... 

因此,unsigned的特殊值是零,signed int和浮点数是-9999而string是空字符串。

现在我想重写一个模板函数,但由于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 == ""; 
} 

是否有可能使这个工作只有一个功能,即使添加其他类与默认值?

+1

你有什么是已经很少。如果你尝试过,你可以用C++ 17中的'constexpr if'折叠成一个。 – StoryTeller

+1

另外,如果你只是明确写入函数中的文字,为什么还要用丑陋的宏来打扰呢? – StoryTeller

+0

@ Rakete1111 - 你连接的问题怎么样,这是一个愚蠢的?模板功能专业化几乎不是任何事情的答案。 – StoryTeller

回答

5

如果您将注意力从定义函数转移开来,并定义名称空值的方式,该解决方案显得很简单。

添加一个暴露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>; } 
0

现在,C++ 17出来的Visual Studio这样可以解决相当容易以其“如果constexpr”功能。让编译器根据需要生成函数。

template<typename T> 
bool isDefault(const T &t) 
{ 
    if constexpr (std::is_unsigned<T>::value) 
    { 
     return t == 0; 
    } 
    else if constexpr (std::is_floating_point<T>::value || std::is_integral<T>::value) 
    { 
     return t == -9999; 
    } 
    else if constexpr (std::is_same<T, CString>::value) 
    { 
     return t == ""; 
    } 
    else if constexpr (std::is_same<T, COleDateTime>::value) 
    { 
     return t.GetStatus() == COleDateTime::null; 
    } 
}