在模板化类的特殊情况下将虚函数定义为纯函数

Wor*_*der 0 c++ pure-virtual template-specialization c++14

我试图定义一个模板化的基类,它定义了一个由用户覆盖的虚拟接口.在某些情况下,拥有此方法的默认实现是有意义的,但对于所有类型参数都不是这样.考虑一下:

template<typename T>
struct supplier
{
    virtual std::unique_ptr<T> supply(std::istream& moreData) = 0;
};
Run Code Online (Sandbox Code Playgroud)

现在我想提供以下默认实现,因为它T是默认的constructible(std::is_default_constructible):

std::unique_ptr<T> supply(std::istream& moreData)
{
    return std::unique_ptr<T>(new T);
}
Run Code Online (Sandbox Code Playgroud)

问题不在于如何为适当的方法定义此函数,T而是如何使其显示为纯虚函数 - 从而强制用户实现 - 当它未定义时,如果是正常的虚函数.

我想我只是缺少一些明显的解决方案.我试图专门化,struct supplier但这意味着我必须两次定义接口的其余部分,所以它绝对不是一个扩展解决方案.这也意味着我必须提供两次接口的其余部分.

对于具有许多虚拟功能的丰富基类,是否有一个经济实惠的解决方案,可以提供实现还是纯虚拟?

T.C*_*.C. 5

将您需要专门化的部分提取到单独的类模板中,然后从中继承.

namespace details {
    template<class T, bool = std::is_default_constructible<T>::value>
    struct supplier_base
    {
        virtual std::unique_ptr<T> supply(std::istream& moreData) = 0;
    };

    template<class T>
    struct supplier_base<T, true>
    {
        virtual std::unique_ptr<T> supply(std::istream& moreData)
        {
            return std::unique_ptr<T>(new T);
        }
    };
}

template<class T>
struct supplier : details::supplier_base<T> { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

  • @WorldSEnder不,这是ODR违规的秘诀. (2认同)