I am trying to figure out the advantages and disadvantages of the CRTP idiom as opposed to template specialization. Let's say I want to create a "Renderer" class, and the renderer will either be implemented using "Vulkan" or "OpenGL".
With CRTP:
template <typename T>
class Renderer
{
public:
void draw(Shape s) { static_cast<T*>(this)->drawImpl(s); };
};
class VulkanRenderer : public Renderer<VulkanRenderer>
{
public:
void drawImpl(Shape s) { /* Vulkan implementation */};
};
class OpenGLRenderer : public Renderer<OpenGLRenderer>
{
public:
void drawImpl(Shape s) { /* OpenGL implementation */ };
};
With template specialization and class tags:
class Vulkan;
class OpenGL;
template<typename T>
class Renderer
{
public:
Renderer() { assert(false, "Type not support"); }
void draw(Shape s);
};
template<>
class Renderer<Vulkan>
{
public:
void draw(Shape s) { /* Vulkan implementation */ };
};
template<>
class Renderer<OpenGL>
{
public:
void draw(Shape s) { /* OpenGL implementation */ };
};
Are there certain advantages of the one method over the other? Are there certain things I can do with the one that I won't be able to do with the other? Are there any alternatives for static polymorphism techniques?
Also, is there any advantage to either of these methods of simply defining separate classes such as "VulkanRenderer" and "OpenGLRenderer". Also, would concepts perhaps not be a better way that both of these?