C++ 在模板类的特殊情况下,将虚函数定义为纯函数
我试图定义一个模板基类,该基类定义了一个由用户重写的虚拟接口。在某些情况下,使用此方法的默认实现是有意义的,但并非所有类型参数都是如此。考虑这一点:C++ 在模板类的特殊情况下,将虚函数定义为纯函数,c++,c++14,template-specialization,pure-virtual,C++,C++14,Template Specialization,Pure Virtual,我试图定义一个模板基类,该基类定义了一个由用户重写的虚拟接口。在某些情况下,使用此方法的默认实现是有意义的,但并非所有类型参数都是如此。考虑这一点: template<typename T> struct supplier { virtual std::unique_ptr<T> supply(std::istream& moreData) = 0; }; 问题不在于如何为适当的T定义此函数,而在于如何使其在未定义时显示为纯虚拟函数,从而强制用户实现,如
template<typename T>
struct supplier
{
virtual std::unique_ptr<T> supply(std::istream& moreData) = 0;
};
问题不在于如何为适当的T
定义此函数,而在于如何使其在未定义时显示为纯虚拟函数,从而强制用户实现,如果它是普通虚拟函数的话。
我想我只是错过了一些显而易见的解决办法。我试图专门化struct-supplier
,但这意味着我必须定义接口的其余部分两次,因此它肯定不是一个可扩展的解决方案。这也意味着我必须提供接口的其余部分两次
对于具有许多虚拟函数的富基类,是否有一个价格合理的解决方案,这些函数可以提供实现,也可以是纯虚拟的?将需要专门化的部分提取到单独的类模板中,然后从中继承
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> { /* ... */ };
名称空间详细信息{
模板
结构供应商库
{
虚拟std::唯一ptr供应(std::istream&moreData)=0;
};
模板
结构供应商库
{
虚拟std::唯一ptr供应(std::istream&moreData)
{
返回std::unique_ptr(新T);
}
};
}
模板
结构供应商:详细信息::供应商库{/*…*/};
将需要专门化的部分提取到单独的类模板中,然后从中继承
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> { /* ... */ };
名称空间详细信息{
模板
结构供应商库
{
虚拟std::唯一ptr供应(std::istream&moreData)=0;
};
模板
结构供应商库
{
虚拟std::唯一ptr供应(std::istream&moreData)
{
返回std::unique_ptr(新T);
}
};
}
模板
结构供应商:详细信息::供应商库{/*…*/};
在这种情况下,是否建议将基类隐藏在匿名命名空间中?@WorldSEnder否,这是违反ODR的原因。在这种情况下,是否建议将基类隐藏在匿名命名空间中?@WorldSEnder否,这是违反ODR的原因。