I want to check if a data field is valid (valid means being not null and not filled with the default value)
Basically
return (!connector->IsNull(field_id) and connector->Get<type>Default(field_id, default_value))
But "type" can be one of many types (string, int64, etc...) so there are 5-6 different functions. I made a helper function for it and I'm trying to pass in the relevant 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);
}
And I'm calling the helper function with....
IsValidField(connector, connector->GetStringWithDefault,20,"")
I get the error "error: reference to non-static member function must be called " because GetStringWithDefault isnt a static function, how do I fix this?
Alternately, is there a way of making it slightly less awkward?
Two possible solutions, one is using
std::bind
and the other is usingstd::mem_fn
.For the solution using
std::bind
it could look something likeThen call it like
For the
std::mem_fn
solution, maybe something likeAnd call it like
Perhaps not the most neat, but the most trivial solution seems to be to wrap everything into lambda:
IsValidField(connector, [connector]() -> T {return connector->GetStringWithDefault(20, "")})
But then you need to adjust the
IsValidField
signature accordingly.There are two things going on here. Do one thing at a time.
Clean up how to call the
GetStringWithDefault
, so you can get something based off its type without knowing the name of the function, as follows:repeat for each supported type. Now,
GetWithDefault<Bob>{}(*connector, id, default_bob)
does what you want.Now the null version:
This moves the association between
T
and the gettor into a helper typeGetWithDefault
, where we implement it via explicit specialization (sort of like a traits class).