了解模板部分专业化

时间:2014-08-21 20:02:57

标签: c++ templates

我试图理解模板部分特化的概念。但是我似乎把它与模板专业化混淆了。我正在考虑以下两个例子

template <typename T> 
struct test
{
   ///Some stuff
};

template <> //Specialization
struct test<int*>
{
   ///Some stuff
};


template<typename t> //Partial specialization
struct test<t*>
{
   ///Some stuff
};

我正在尝试以下

test<int*> s;

,这会调用专用模板。我怎样才能调用部分专业课程。有人可以用一个例子解释部分模板和专用模板之间的区别吗?

更新

在完成答案后,我意识到只有当参数的一个子集需要专门化时,部分模板专业化才能提供帮助。所以我试过这样的事情

template <>
struct test<int*>
{
};


//Partial Specialized
template<typename t>
struct test<t, std::string>
{
};

test<int*,std::string> s;  //Error : Too many arguments for class template

为什么?

4 个答案:

答案 0 :(得分:5)

简而言之,在谈论课程模板时:

所有3个案例的例子:

#include <iostream>

template<typename T, typename U> //Primary template
struct test
{
   void foo() { std::cout << "\nPrimary"; }
};

template <typename T> //Specialization
struct test<T, int*>
{
   void foo() { std::cout << "\nPartial Specialization"; }
};


template<> //Full specialization
struct test<int*, int*>
{
   void foo() { std::cout << "\nFull Specialization"; }
};

int main()
{
    test<int, double> t1;
    t1.foo();

    test<double, int*> t2;
    t2.foo();

    test<int*, int*> t3;
    t3.foo();
}

输出:

  

主要

     

部分专业化

     

完全专业化

<强> Live demo.


要回答您的更新:

  • 模板专精化无法添加参数,它只能专门化现有参数

答案 1 :(得分:1)

这是一个模板:

tempalte <typename A, typename B>
class Foo {};

你可以把它专门化:

template <>
class Foo<int, int> {};

您也可以将其中一个参数保留为免费(部分特化):

template <typename B>
class Foo<std::string, B> {};

答案 2 :(得分:1)

部分专业化可以达到两种效果。

一,你可以修复&#34;一个或多个模板参数到具体值,同时保持其他&#34;未绑定。&#34;这是一个例子:

template <class A, class B>
struct Foo  // The primary template
{
  static const int i = 0;
};

template <class A>
struct Foo<A, int>  // Partial specialisation which "fixes" B
{
  static const int i = 1;
};

template <>
struct Foo<char, int>  // Full specialisation
{
  static const int i = 2;
};

int main()
{
  std::cout << Foo<char, double>::i;  // 0
  std::cout << Foo<double, int>::i << Foo<void, int>::i;  // 11
  std::cout << Foo<char, int>::i;  //2
}

二,您可以为更具体的(仍然是通用的)模板参数版本提供模板的替代定义:

template <class A>
struct Bar  // Primary template
{
  static const int i = 0;
};

template <class A>
struct Bar<A*>  // Patrial specialisation for pointers
{
  static const int i = 1;
};

template <>
struct Bar<int*>  // Full specialisation
{
  static const int i = 2;
};

int main()
{
  std::cout << Bar<int>::i;  // 0
  std::cout << Bar<void*>::i << Bar<int**>::i;  // 11
  std::cout << Bar<int*>::i;  // 2
}

这正是您的原始代码所做的。

你当然也可以将两者结合起来,如下:

template <class A>
struct Foo<std::vector<A>, int>  // Partial specialisation of primary Foo from above, for any std::vector and an int
{
  static const int i = 3;
};

答案 3 :(得分:0)

请查看有关模板专业化的link

template <>

将处理特定类型的方式,而

template<typename t> //Partial specialization
struct test<t*>

您是如何处理泛型类型的。当然

test<int*> s;

调用专用模板,因为这是您在上面指定的。要调用部分专用,请使用任何其他类型的模板进行调用。例如

test<char*> s;