I have a set of classes which have many very similar methods, grouped into 2 call signatures. These calls are of the form:
bool fn( const std::string& )
and bool fn( const std::vector<std::string>& )
I need to do some common logic around each call and I'm trying to make my life easy but without much luck. Conceptually, the wrapper logic signature looks like the following:
bool wrap( config::method, key, values, flag )
I have code that compiles but it is more complicated than I want. This is the actual signature (there will be two wrappers, one for each signature type):
template <typename T, bool(T::*fn)(const std::string&)>
bool CFG_STR( T& cfg, const char* key, Nodes data, bool flag ) { /* ... cfg.*fn(x) ... */ }
and this is the caller:
configClassWithVeryLongName config;
success &= CFG_STR<
configClassWithVeryLongName,
&configClassWithVeryLongName::methodCall
>( config, "key", dataStore, configFlag );
Is there a more compact and less fragile way to write this? I can reduce it to this:
#define MAC_STR(c,m,k,d,f) CFG_STR<typeof( c ), m>( c, k, d, f )
configClassWithVeryLongName config;
success &= MAC_STR( config, &configClassWithVeryLongName::methodCall, "key", dataStore, configFlag );
I would really like to remove the class name prefix and simply pass methodCall
or "methodCall", and not use CPP macros. Is there a clever way to do this cleanly? I've tried a few things like combining typeof
with the #
paste macro to form the method name but without any success. Modifying the 'config...' classes is not an option because they do not all inherit from a common base class.
Thanks.
CodePudding user response:
You can just pass the member pointer as function argument:
template <typename T>
bool CFG_STR( T& cfg, bool(T::*fn)(const std::string&), const char* key, Nodes data, bool flag ) { /*...*/ }
And instead of repeating the class name you can just write decltype(config)
:
success &= CFG_STR( config, &decltype(config)::methodCall, "key", dataStore, configFlag );