2017-07-25 62 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; 
    } 
}