I think the 2D vs 3D instantiation can be solved by templating over dimension.
For determining type, maybe this example would help?
https://itk.org/Doxygen/html/Examples_2IO_2TransformReadWrite_8cxx-example.html
using ReadCompositeTransformType =
itk::CompositeTransform<ReadScalarType, Dimension>;
auto it = transforms->begin();
if (!strcmp((*it)->GetNameOfClass(), "CompositeTransform"))
{
ReadCompositeTransformType::Pointer compositeRead =
static_cast<ReadCompositeTransformType *>((*it).GetPointer());
compositeRead->Print(std::cout);
}