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

Sau*_*729 39 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

}
Run Code Online (Sandbox Code Playgroud)

Struct <float>由编译器实例化

template <typename T=float>
struct Struct
{
    float x;
}
Run Code Online (Sandbox Code Playgroud)

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

Arm*_*yan 42

4个概念:

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

显式实例化::这是当你告诉编译器用给定类型实例化模板时,就像这样

template Struct<char>; //used to control the PLACE where the template is inst-ed
Run Code Online (Sandbox Code Playgroud)

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

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

template<class T> class Struct<T*> {...} //partial specialization for pointers
Run Code Online (Sandbox Code Playgroud)

  • 在C++标准中(但不是其他地方),还有隐式特化,这是编译器在实例化模板时所做的事情,并且没有选择明确的特化. (5认同)

sbi*_*sbi 16

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

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

如果一个专业化存在,那么由专门指定的(一组)特殊的模板参数(S),即专业化的实现是用来代替什么,编译器会创建.


Cas*_*Cow 11

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

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

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

template<> std::string convertToString( const std::string & t )
{
   return t;
}
Run Code Online (Sandbox Code Playgroud)

你也可以专攻课程.

现在实例化:这样做是为了允许您将某些类型的编译移动到一个编译单元中.这可以节省编译时间,有时也可以节省代码膨胀.假设我们将上面的内容变成一个名为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
 };
Run Code Online (Sandbox Code Playgroud)

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

 extern template class StringConvert<int>;
Run Code Online (Sandbox Code Playgroud)

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

 template class StringConvert<int>;
Run Code Online (Sandbox Code Playgroud)

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


Joh*_*itb 7

概观

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

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

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


Fra*_*cis 6

在c ++ 11中.

实例:

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

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

template test<int>;//explicit instantiation
Run Code Online (Sandbox Code Playgroud)

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

test<int> a;//implicit instantiation
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

最有用的模板特化可能是您可以为不同的模板参数创建不同的模板,这意味着您可以为不同的模板参数提供不同的类或函数定义.

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;
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)