2015-11-06 47 views
0

我要檢查,如果數據字段是有效的(有效的手段是不空,不填充默認值)通過STD傳遞一個成員函數::功能

基本上

return (!connector->IsNull(field_id) and connector->Get<type>Default(field_id, default_value)) 

但「類型「可以是多種類型之一(string,int64等),所以有5-6個不同的功能。我做了一個輔助功能,它和我試圖在相關GetDefault通...

template<typename T> bool IsValidField(std::unique_ptr<Connector>& connector, const std::function<T(int, T)> &GetDefault, int field_id, T default_value){ 
    return (!connector->IsNull(field_id) && connection->GetDefault(field_id, default_value) != default_value); 
} 

我打電話輔助函數....

IsValidField(connector, connector->GetStringWithDefault,20,"") 

我得到錯誤「error:引用非靜態成員函數必須調用 」,因爲GetStringWithDefault不是一個靜態函數,我該如何解決這個問題?

或者,有沒有辦法讓它稍微笨拙一點?

回答

1

兩種可能的解決方案,一種是使用std::bind,另一種是使用std::mem_fn


對於使用std::bind它可能看起來像

template<typename T, typename F> 
bool IsValidField(std::unique_ptr<Connector>& connector, F GetDefault, 
        int field_id, T default_value) 
{ 
    return (!connector->IsNull(field_id) && 
      GetDefault(field_id, default_value) != default_value); 
} 

然後調用它像

IsValidField(

IsValidField(connector, 
      std::bind(&ClassForConnector::GetStringWithDefault, _1, _2), 
      20,""); 

對於std::mem_fn的解決方案,可能像

的解決方案

,並調用它像

IsValidField(connector, 
      std::mem_fn(&ClassForConnector::GetStringWithDefault), 
      20,""); 
+0

是否有可能以某種方式刪除「連接器」參數? – Narabhut

+0

@Narabhut除非你刪除'connector-> IsNull(field_id)'檢查。 –

1

也許不是最整齊的,但最瑣碎的解決方案似乎是一切包裝成拉姆達:

IsValidField(connector, [connector]() -> T {return connector->GetStringWithDefault(20, "")})

但你需要調整相應的IsValidField簽名。

+0

爲此,我甚至不需要該功能?如果他們是這樣的一個內線隊員,我想我可以做4-5個。 – Narabhut

0

這裏有兩件事情。一次做一件事。

清理如何調用GetStringWithDefault,這樣你就可以根據東西掉它的類型,而無需知道函數的名稱,具體如下:

namespace impl { 
    template<class T, T Connector::*Method(int, T const&)> 
    struct GetWithDefault { 
    T operator()(Connector const& connector, int id, T const& default) const { 
     return (connector.*Method)(id, default); 
    }; 
} 

template<class T> 
struct GetWithDefault; 

template<>struct GetWithDefault<std::string>: 
    impl::GetWithDefault<std::string, &Connector::GetStringWithDefault> 
{}; 

重複每一個支持的類型。現在,GetWithDefault<Bob>{}(*connector, id, default_bob)做你想做的。

現在空的版本:

template<class T> 
bool IsValidField(Connector const& connector, int id, T const& default_value) { 
    return !connector.IsNull(id) && (GetWithDefault<T>{}(connector, id, default_value)!=default_value); 
    } 
}; 

這使T和gettor之間的關聯爲輔助型GetWithDefault,在這裏我們通過明確的分工實現它(有點像一個traits類)。

相關問題