Search code examples
c++templatesvisual-c++template-meta-programmingsfinae

Definition of pure virtual method while using templated class with sfinae


I'm trying to learn and use sfinae, this is my first attemt to do so. I have following code:

template<class CoreType, typename std::enable_if_t<std::is_base_of_v<Core, CoreType>>* = nullptr>
class Window
{
protected:
    std::shared_ptr<Engine<CoreType>> _engine;
public:
    virtual ~Window() = 0;
};

template<class CoreType, typename std::enable_if_t<std::is_base_of_v<Core, CoreType>>* = nullptr>
Window<CoreType>::~Window() {} // <- problem is here

I get this error: E0498 template argument list must match the parameter list

Which seems like i should somehow provide the dummy parameter of sfinae but how ?

If i remove the , typename std::enable_if_t<std::is_base_of_v<Core, CoreType>>* = nullptr which causing the problem, it works like it should, but i want to learn how to use sfinae and i just can find this partical case on google. Can anyone help me with this please ? Thank you


Solution

  • You're telling the compiler that the ~Window () function is part of the Window<CoreType> class. However, there is no such class. The class you defined takes two template parameters (the fact that one is used for SFINAE doesn't matter).

    You're also using typename std::enable_if_t<...>, but the _t suffix indicates that the typename is already done for you. So effectively you have typename typename std::enable_if<...> there.

    Also note that you shouldn't repeat default template arguments, just as you shouldn't repeat default function arguments for a function definition.

    Finally, you have to give all arguments a name in order to be able to refer to them. So the unnamed std::enable_if_t needs a name.

    All that together becomes:

    template <class CoreType,
        std::enable_if_t<std::is_base_of_v<Core, CoreType>> * Enable>
    Window<CoreType, Enable>::~Window() {}