Home > Back-end >  How to use factory method with multi string parameters to create a template class?
How to use factory method with multi string parameters to create a template class?

Time:09-17

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();
}
  • Related