2

我正在阅读 Primer C++ > 函数冒险 > 模板 > 显式专业化。

为了说明显式专业化的原因/用途,我们举例说明了一个案例。考虑一个可以交换任何类型(int、double、struct等)的交换模板函数(我认为代码很明显,所以这里不需要写)

但是有一个特定的结构(称为作业),您只想交换其中的两个成员,而让其余成员保持原样。您将需要不同的定义,因此您必须进行显式专业化。

在同一节中有这样的声明:-“专业化覆盖常规模板,非模板函数覆盖两者。” 为什么不为此用途创建一个(常规)功能?那么常规/非模板会覆盖模板吗?

如果我的解决方案是正确的,那么什么是显式专业化的好例子?

4

3 回答 3

5

显式特化的用例之一是避免在实际函数中发生某些更改时跳过常规template函数。要了解以下示例:

template<typename T1, typename T2>
void foo(T1 o1, T2 o2)  // template function
{}
void foo(int o1, int o2) // regular function overloaded
{}

到现在还好。现在过了一段时间你必须改变定义template<> foo()

template<typename T1, typename T2, typename T3> // new parameter added
void foo(T1 o1, T2 o2, T3 o3)  // template function
{}

您相应地更改了所有调用foo(),但您错过/弄乱了更改常规重载函数foo()。那么,就是一场灾难!因为编译会顺利进行,并且常规调用会被悄悄地替换template<> foo(),这是不希望的。

现在,如果有一个明确的专业化,例如,

template<>
void foo(int o1, int o2) // explicit specialization
{}

那么这个函数会因为参数不匹配而给你编译错误,这会提醒你相应的变化。

另一种用法或(区别)是可以将显式专用函数包含在头文件中,而无需担心多符号链接错误。请注意,显式专业化也有其自身的缺点,但我演示了它的一个好的方面。

于 2011-06-20T04:47:53.493 回答
1

为什么不为此用途创建一个(常规)功能?那么常规/非模板会覆盖模板吗?

当然,如果您可以的话,您可以使用常规函数重载而不是显式函数模板特化。但是如果显式使用函数模板(通过指定模板参数),则不会使用常规函数重载。

例子:

你有功能模板:

template< class T >
void foo( T& x, const T& y )
{
...
}

然后,如果您指定函数重载:

void foo( double& x, const double& y )
{
....
}

在这样的代码中:

template< class T >
void some_function( T& x )
{
    T y;
    ......
    foo<T>( x, y );
}

void foo( double& x, const double& y )永远不会使用函数重载。

但是如果你指定函数模板特化

template<>
void foo<double>( double& x, const double& y )
{
....
}

some_function如果你打电话,然后会使用你的专业

double x;

some_function(x);

某处。

于 2011-06-20T10:16:02.027 回答
0

标准函数可能是特化的,但可能不会被重载,仅举一个例子。另一个例子是类型是不可推导的,并且您拥有使用显式模板参数调用它们的现有代码——那么您的重载毫无价值。

于 2011-06-20T10:35:26.677 回答