I have a factory function with two string parameters (each parameter indicates a class). How could I reduce using if
branches?
A create_A(string type, string order){
if (type=="LLT" && order == "AMD"){
return A<LLT, AMD>();
}
elif(type=="LLT" && order=="COLAMD"){
return A<LLT, COLAMD>();
}
elif(type=="LU" && order=="AMD"){
return A<LU, AMD>();
}
elif(type=="LU", && order="COLAMD"){
return A<LU, COLAMD>();
}
}
UPDATE: I have tried this, too. But I would still like to reduce the if
branches.
std::unique_ptr<Base> create_A(string type, string order){
if (type=="LLT" && order == "AMD"){
return std::make_unique<Derived<LLT, AMD>>();
}
else if(type=="LLT" && order=="COLAMD"){
return std::make_unique<Derived<LLT, COLAMD>>();
}
else if(type=="LU" && order=="AMD"){
return std::make_unique<Derived<LU, AMD>>();
}
else if(type=="LU", && order="COLAMD"){
return std::make_unique<Derived<LU, COLAMD>>();
}
}
CodePudding user response:
One way to reduce this code would be to use a std::(unsorted_)map
with a std::pair<std::string,std::string>
as the key type, and lambdas or free functions as the value type.
However, a function can't return different types, and A<w,x>
is a distinct type from A<y,z>
. If you really want this to work, you should derive A
from a non-template base class, return a pointer to that base class, and then create your A
objects dynamically, eg:
using key_type = std::pair<std::string, std::string>;
using func_type = std::unique_ptr<Base> (*)();
#define MAKE_ENTRY(type, order) {{#type, #order}, []() -> std::unique_ptr<Base> { return std::make_unique<Derived<type, order>>(); }
std::unique_ptr<Base> create_A(string type, string order){
static std::unordered_map<key_type, func_type> A_types = {
MAKE_ENTRY(LLT, AMD),
MAKE_ENTRY(LLT, COLAMD),
MAKE_ENTRY(LU,AMD),
MAKE_ENTRY(LU, COLAMD)
}:
auto func = A_types.at(std::make_pair(type, order));
return func();
}