I want to create new instances of programs depending on a file extension. Unfortunately I cannot change the interface, because filename is a command-line argument. Also, I don't like that if I want to add new program, I have to deal with if-else statements. I thought about maps for storing (string, type_index), but apparently this approach doesn't work with templates. Furthermore, I tried to deal with std::enable_if by passing a constexpr string comparison function, but that obviously doesn't work either. I suppose I can somehow extend the latter approach by creating a bunch of functions and pick one depending on a string comparison. Basically, what I want is to achieve extensibility and be compliant with SOLID principles.
std::shared_ptr<Program> Program::fromFile(const Path& file){
auto extension = file.extension();
if(extension == "cpp"){
return std::make_shared<CppProgram>(file);
} else if(extension == "py"){
return std::make_shared<PythonProgram>(file);
} else if(extension == "java"){
return std::make_shared<JavaProgram>(file);
} else if(extension == "go"){
return std::make_shared<GoProgram>(file);
} else {
throw std::runtime_error("unknown file extension " + extension);
}
}