[英]Let template partial specializations share member functions with general instantiations
Suppose I have a class template Foo
: 假设我有一个类模板
Foo
:
template<typename T, typename U>
struct Foo {
~Foo() = default;
// I want to reuse these methods for all instantiations of Foo
void bar() {}
void poi() {}
};
I want to specialize the destructor for any Foo<T, int>
, but I want Foo<T, int>
to share the other member functions with the general instantiations. 我想专门针对任何
Foo<T, int>
的析构函数,但我希望Foo<T, int>
与常规实例共享其他成员函数。 But if I try to do: 但是,如果我尝试这样做:
template<typename T>
Foo<T, int>::~Foo()
{}
outside the class, it doesn't compile, the error being "invalid use of incomplete type struct Foo<T, int>
". 在类外部,它不会编译,错误是“无效使用不完整类型
struct Foo<T, int>
”。 What does this error mean, and how can I achieve what I'm trying to do? 此错误是什么意思,我如何实现自己的目标?
It is not possible to partially specialise a (non-templated) member function. 不可能部分专门化(非模板化的)成员函数。 You need to specialise the whole class.
您需要对整个班级进行专业培训。
One way to do what you want is to inherit the common functions. 一种实现所需功能的方法是继承通用功能。
template<typename T, typename U> struct MemberProvider
{
~MemberProvider() = default;
void bar() {};
void poi() {};
};
template<typename T, typename U>
struct Foo : public MemberProvider<T, U>
{
~Foo() = default;
// Optionally, you can still do this.
// However, note that these HIDE the inherited functions
void bar() {};
void poi() {};
};
template<typename T> struct Foo<T, int> : public MemberProvider<T, int>
{
~Foo() {};
};
Note you will also need to include any members acted on by the common functions in the inherited class. 注意,您还需要在继承的类中包括所有由通用函数作用的成员。
However, I would suggest the above represents a code smell. 但是,我建议以上内容代表代码气味。 If I saw code like the above in a production environment, I'd be contemplating the presence of a design flaw.
如果在生产环境中看到上面的代码,我将考虑存在设计缺陷。 Bear in mind that, when destructing such a class, the most derived destructor is invoked before base class destructors.
请记住,在销毁此类时,将在基类销毁器之前调用最派生的销毁器。
MemberProvider
is also not a polymorphic base. MemberProvider
也不是多态基础。
You can explicitly specialize member functions of class templates, but you cannot partially specialize them - which is what you're trying to do. 您可以显式地专门化类模板的成员函数,但是不能部分地专门化它们-这是您要尝试的工作。
If you need to partially specialize the destructor in a way that keeps the generic version defaulted, you'll have to partially specialize the whole class template: 如果您需要以使通用版本保持默认状态的方式来部分化析构函数,则必须部分化整个类模板:
template <class T, class U>
struct FooCommon {
~FooCommon() = default;
void bar() {}
void poi() {}
};
template <class T, class U>
struct Foo : FooCommon<T, U> { };
template <class T>
struct Foo<T, int> : FooCommon<T, int> {
~Foo() {
// special logic here
}
};
If foo
and poi
do things that depend on the template parameters, then you could extract your specialised destructor behaviour into a separate class, eg, 如果
foo
和poi
行为取决于模板参数,则可以将专门的析构函数的行为提取到单独的类中,例如,
#include <iostream>
template <typename T, typename U>
struct Foo;
template <typename T, typename U>
struct FooDestructorTraits
{
static void destroy(Foo<T, U> * ptr)
{
std::cout << "default" << std::endl;
}
};
template <typename U>
struct FooDestructorTraits<int, U>
{
static void destroy(Foo<int, U> * ptr)
{
std::cout << "special" << std::endl;
}
};
template <typename T, typename U>
struct Foo
{
~Foo() noexcept { FooDestructorTraits<T, U>::destroy(this); }
void bar() {}
void baz() {}
};
int main() {
Foo<void, void> x;
Foo<int, void> y;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.