模板特定方法

时间:2014-12-10 18:32:29

标签: c++ templates

如果我有课程A

template <typename T>
class A { public: void print() const; };

我可以为我所做的特定模板值编写我的方法print的特定版本

template<> void A<bool>::print() const { printf("A w/ type bool\n"); }
template<> void A<int>::print()  const { printf("A w/ type int\n");  }

并且调用方法print将只调用良好实现的代码(编译器的代码告诉我,如果我没有特定模板的实现。


现在,如果我的班级B的模板中有多个类型

template <typename T1, typename T2>
class B { public: void print() const; };

如果我尝试像以前一样做,那就让我们说T2

template<typename T1> void B<T1,bool>::print() const { printf("B w/ type bool\n"); }

我收到编译错误:

error: invalid use of incomplete type 'class B<T1,bool>'
error: declaration of 'class B<T1, bool>'

我做错了什么?

修改

我的真实生活B类包含其他方法,我不想指定(它们在一般情况下工作)

对部分指定的类进行decalred会使这些泛型方法无法原生使用

4 个答案:

答案 0 :(得分:2)

你不能部分专门化一个功能/方法。

但你可以局部专注于整个班级:

template <typename T1, typename T2> class B;

template<typename T1> class B<T1, bool>
{
public:
    void print() const { printf("B w/ type bool\n"); }
};

答案 1 :(得分:2)

  

我做错了什么?

template<> void A<bool>::print() const { printf("A w/ type bool\n"); }
template<> void A<int>::print()  const { printf("A w/ type int\n");  }

这些成员函数与普通函数类似,它们不是具有未替换参数的模板,因此您只是提供符号的定义,这些函数将在调用这些函数时使用。 (和普通函数一样,如果这些定义在标题中并且你没有声明它们inline,你将会得到多个定义错误。)

template<typename T1> void B<T1,bool>::print() const { printf("B w/ type bool\n"); }

这是不一样的,这是为类模板部分特化的成员函数提供定义。即,它是一个模板,用于为该部分特化的成员生成代码,但您尚未声明任何此类部分特化,因此您无法定义其成员。

您可以先通过定义部分特化来进行编译:

// primary template
template <typename T1, typename T2>
class B { public: void print() const; };

// partial specialization
template<typename T1>
class B<T1,bool> { public: void print() const; };

template<typename T1> void B<T1,bool>::print() const { printf("B w/ type bool\n"); }

然而,为了定义一个或两个成员的部分专业化而必须重复整个类模板定义通常是不方便的,因此可能值得采用其他答案中显示的替代设计之一。

答案 2 :(得分:0)

使用模板,最好将专业化的每个部分分解为自己的模板函数或特征类。

这是一个干净的方式来做你想做的事情:

template<typename T>
const char* type_name()
{
    return "unknown";
};

template<>
const char* type_name<int>()
{
    return "int";
}

template<>
const char* type_name<bool>()
{
    return "bool";
}

struct foo {};

template<>
const char* type_name<foo>()
{
    return "my custom foo";
}

struct bar {};

template <typename T>
class A {
    public:
    void print() const {
        cout << "A w/ type " << type_name<T>() << '\n';
    }
};

int main() {
    A<bool> ab;
    A<int> ai;
    A<foo> af;
    A<bar> abar;

    ab.print();
    ai.print();
    af.print();
    abar.print();

    return 0;

}

输出:

A w/ type bool
A w/ type int
A w/ type my custom foo
A w/ type unknown
Program ended with exit code: 0

答案 3 :(得分:0)

使用标签调度,您可以执行以下操作:

#include <iostream>

template<typename A, typename B>
class X
{
    private:
    template <typename U> struct Tag {};

    template <typename U>
    void print(Tag<U>) const;

    void print(Tag<bool>) const { std::cout << "bool\n"; }
    void print(Tag<int>) const{ std::cout << "int\n"; }

    public:
    void print() const { print(Tag<B>()); }
};

int main()
{
    X<void, bool>().print();
    X<void, int>().print();
}