c ++模板中的实例化和专业化之间的区别

时间:2010-10-12 12:26:22

标签: c++ templates

C ++模板上下文中的特化和实例化有什么区别。从我到目前为止所读到的内容,以下是我对专业化和实例化的理解。

template <typename T>
struct Struct
{

     T x;
};

template<>
struct Struct <int> //specialization
{

    //code
};

int main()
{
   Struct <int> s; //specialized version comes into play
   Struct <float> r; // Struct <float> is instantiated by the compiler as shown below

}

编译器{/ 1}实例化

Struct <float>

我对模板实例化和专业化的理解是否正确?

6 个答案:

答案 0 :(得分:38)

4个概念:

(隐式)实例化 :这就是你所说的实例化

显式实例化 :这是你告诉编译器用给定类型实例化模板的时候,比如这个

template Struct<char>; //used to control the PLACE where the template is inst-ed

(显式)专业化: 这就是您所称的专业化

部分特化 这是为类型子集的模板提供替代定义,如下所示:

template<class T> class Struct<T*> {...} //partial specialization for pointers

答案 1 :(得分:15)

  

C ++模板上下文中的特化和实例化有什么区别?

通常(不存在特化)编译器将在使用模板时创建 实例化 ,方法是替换实际模板参数(int在您的示例中)为正式的模板参数(T),然后编译生成的代码。

如果存在 专门化 ,那么对于该专业化指定的(一组)特殊模板参数,将使用该专业化的实现而不是编译器会创建什么。

答案 2 :(得分:9)

模板特化实际上会更改特定类型的模板行为。例如,转换为字符串:

template<typename T> std::string convertToString( const T& t )
{
   std::ostringstream oss;
   oss << t;
   return oss.str();
}

让我们专注于,虽然我们的类型已经是std :: string,因为它通过ostringstream是无意义的

template<> std::string convertToString( const std::string & t )
{
   return t;
}

你也可以专攻课程。

现在实例化:这样做是为了允许您将某些类型的编译移动到一个编译单元中。这可以节省编译时间,有时也可以节省代码膨胀。 假设我们将上面的内容变成一个名为StringConvert的类而不是函数。

template<typename T>
class StringConvert
{
 public:
  // 4 static functions to convert from T to string, string to T,
   // T to wstring and wstring to T using streams
 };

我们将很多整数转换为字符串,以便我们可以实例化它:把它放在一个标题中

 extern template class StringConvert<int>;

将它放在一个编译单元中:

 template class StringConvert<int>;

请注意,上面也可以使用实际上没有内联实现的函数来完成(没有标题中的extern)。您的一个编译单元将实现它们。但是,您的模板仅限于实例化类型。有时在模板具有虚拟析构函数时完成。

答案 3 :(得分:7)

概述

  • 专业化:将模板参数替换为类模板或函数模板的模板参数时获得的类,函数或类成员。

  • 实例化:从模板或类模板成员创建特化的行为。可以从部分特化,类模板成员或主类或函数模板之外创建特化。

显式特化是在没有实例化的情况下定义类,函数或成员显式的特殊化。

答案 4 :(得分:6)

在c ++ 11中。

<强>实例

使用给定的模板参数实例化模板

template <typename T>
struct test{ T m; };

template test<int>;//explicit instantiation

导致带有标识符test<int>的结构的定义

test<int> a;//implicit instantiation

如果template <typename T> struct test之前已经使用参数T = int进行了实例化(显式或隐式),那么它只是一个结构实例化。否则,它将首先隐式地使用参数template <typename T> struct test实例化T = int,然后实例化struct test<int>的实例

<强>专业化:

专业化仍然是模板,您仍需要实例化才能获得真实的代码。

template <typename T>
struct test{ T m; };
template <> struct test<int>{ int newM; } //specialization

最有用的模板专业化可能是您可以为不同的模板参数创建不同的模板,这意味着您可以为不同的模板参数设置不同的类或函数定义

template<> struct test<char>{ int cm; }//specialization for char
test<char> a;
a.cm = 1;

template<> struct test<long> { int lm; }//specialization for long
test<long> a;
a.lm = 1;

除了上面的完整模板专业化之外,还有(仅限类模板)退出部分模板专业化

template<typename T>
struct test {};
template <typename T> struct test<const T>{};//partial specialization for const T


template <typename A, typename B>
struct test {};
template <typename B> struct test<int, B>{};//partial specialization for A = int

答案 5 :(得分:0)

专用模板不再仅仅是模板。相反,它可以是实际的类或实际的函数。

专业化来自实例化或显式专业化,参见下面的14.7.4。

实例化基于主模板定义。示例隐式类模板实例化,

template<typename T>
class foo {}

foo<int> foo_int_object;

示例显式类模板实例化,

template class foo<double>;

显式专业化与其主要模板的定义不同。

template<>
class foo<bool> {}

//从标准

中提取

14个模板

14.7模板实例化和专业化

4对于给定的参数,可以隐式实例化(14.7.1)实例化的模板特化 列表或明确实例化(14.7.2)。专门化是一个类,函数或类成员 实例化或明确专门化(14.7.3)。