假设我有一个类模板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() {}
};
我想专门针对任何Foo<T, int>
的析构函数,但我希望Foo<T, int>
与常规实例共享其他成员函数。但如果我试着这样做:
template<typename T>
Foo<T, int>::~Foo()
{}
在类之外,它不编译,错误是“无效使用不完整类型struct Foo<T, int>
”。这个错误意味着什么,我怎样才能实现我想做的事情?
答案 0 :(得分:3)
无法部分专门化(非模板化)成员函数。你需要专注于全班。
实现目标的一种方法是继承常用功能。
MemberProvider
请注意,您还需要包含继承类中常用函数所作用的任何成员。
但是,我建议上面代表代码味道。如果我在生产环境中看到如上所述的代码,我会考虑存在设计缺陷。请记住,在破坏这样的类时,在基类析构函数之前调用派生最多的析构函数。 suggestion
也不是多态基础。
答案 1 :(得分:3)
您可以明确地专门化类模板的成员函数,但是您不能对它们进行部分特化 - 这是您正在尝试做的事情。
如果您需要以保持泛型版本默认的方式部分地对析构函数进行特化,则必须部分专门化整个类模板:
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
}
};
答案 2 :(得分:-1)
如果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;
}