如何为所有非数组类型专门化模板?

时间:2018-05-05 21:31:29

标签: c++

假设我有一个模板my_type。我希望它具有一般功能,当T不是数组时有一些额外的功能,当T是数组时有其他功能。

假设我有以下模板:

template <typename T>
class my_class<T> {
public:
    int f1(); // This function is available for all T
    int f2(); // This function is available when T is not an array
    int f3(); // This function is available when T is an array
}

所以,如果我尝试:

my_class<int> c1; my_class<int[3]> c2;
c1.f1(); c2.f1(); // both fine
c1.f2(); c2.f3(); // both fine
c1.f3(); c2.f2(); // both should give a compile error

我知道std::unique_ptr在内部做到这一点。那怎么做呢?

2 个答案:

答案 0 :(得分:4)

另一种方式,使用enable_if。还要注意使用基类来捕获所有常见行为。

#include <type_traits>

template<class T>
struct my_base
{
    int f1();
};

template<class T, typename Enable = void> 
class my_class;

template<class T> 
class my_class<T, std::enable_if_t<std::is_array<T>::value>>
: public my_base<T>
{
public:
    int f3(); // This function is available when T is an array
};

template <typename T>
class my_class<T, std::enable_if_t<not std::is_array<T>::value>> 
: public my_base<T>
{
public:
    int f2(); // This function is available when T is not an array
};

int main()
{
    auto a = my_class<int[]>();
    a.f1();
//    a.f2();
    a.f3();

    auto na = my_class<int>();
    na.f1();
    na.f2();
//    na.f3();
}

答案 1 :(得分:3)

我自己已经弄清楚了。以下代码将完全按照我的要求执行。

template<typename T>
class my_class {
public:
        int f1() { return 1; }
        int f2() { return 2; }
};

template<typename T>
class my_class<T[]> {
public:
        int f1() { return 1; }
        int f3() { return 3; }
};

请注意,必须复制公共函数(f1)的实现。现在有没有办法使用单一实现? (请注意,它不像示例代码中的return 1;那么简单,因此我无法将功能分离为非模板函数)