让模板部分特化与一般实例化共享成员函数

时间:2016-07-18 22:19:53

标签: c++ c++11

假设我有一个类模板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>”。这个错误意味着什么,我怎样才能实现我想做的事情?

3 个答案:

答案 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)

如果foopoi执行依赖于模板参数的事情,那么您可以将专门的析构函数行为提取到单独的类中,例如,

#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;
}