I have code like this:
template<class Command>
void registerCmd() {
Command x{};
// do something with x...
}
namespace Cmd
{
struct GET { /* some methods */ };
struct GETSET { /* some methods */ };
struct DEL { /* some methods */ };
void registerCommands() {
registerCmd<GET>();
registerCmd<GETSET>();
registerCmd<DEL>();
}
}
I like how the code turns out. I was wondering if there is a way this code to be changed to something like this:
namespace Cmd
{
void register() {
// this does not compile
for (TYPE in{ GET, GETSET, DEL })
registerCmd<TYPE>();
}
}
May be with variadic templates?
CodePudding user response:
You can not have a collection of different types in a range based for loop, unless you have them in an array of std::variant
, std::any
or such types.
If you're willing to make the registerCommands
template function which has variadic template arguments as template parameter, with the help of fold expression (since c 17) you might do (provided that the number types are known at compile time):
template<typename... Types>
void registerCommands() {
(registerCmd<Types>(), ...);
}
and function calling
Cmd::registerCommands<Cmd::DEL, Cmd::GETSET, Cmd::GETSET>();
CodePudding user response:
Clarification, probably will help others.
It turns out, the template template class is like this:
template<
template<class, class> class Cmd,
class Protocol,
class DBAdapter,
class Storage,
class Map
>
void registerCmd(Storage &s, Map &m){
//...
}
I still was able to do it with fold, in following way:
template<
class Protocol,
class DBAdapter,
class Storage,
class Map,
template<class, class> typename... Commands
>
void registerCommands(Storage &s, Map &m){
( registerCmd<Commands, Protocol, DBAdapter>(s, m), ... );
}
and here is how I call it:
struct SET { /* some methods */ };
struct SETEX { /* some methods */ };
struct SETNX { /* some methods */ };
struct DEL { /* some methods */ };
struct GETSET { /* some methods */ };
struct EXPIRE { /* some methods */ };
registerCommands<Protocol, DBAdapter, Storage, Map,
SET ,
SETEX ,
SETNX ,
DEL ,
GETSET ,
EXPIRE
>(s, m);
Here are link to the files: