简体   繁体   English

C++ 中的显式专业化

[英]Explicit Specialization in C++

I'm reading Primer C++ > Adventures in Functions > Templates > Explicit Specialization.我正在阅读 Primer C++ > Adventures in Functions > Templates > Explicit Specialization。

To show the reason/use for Explicit Specialization, a case is illustrated.为了显示显式专业化的原因/用途,举例说明。 Consider a swap template function that can swap any type (int, double, struct, etc...) (I think the code is obvious so no need to write it here)考虑一个交换模板 function,它可以交换任何类型(int、double、struct 等...)(我认为代码很明显,所以不需要在这里写)

But there is a specific struct (called job) that you want to only swap two members of, and leave the rest of the members as they are.但是有一个特定的结构(称为作业),您只想交换其中的两个成员,并保持成员的 rest 不变。 You will need a different definition, and so you will have to make an Explicit Specialization.您将需要一个不同的定义,因此您将必须进行显式专业化。

There is this statement in the same section:- "A specialization overrides the regular template, and a non-template function overrides both."在同一部分中有这样的声明:-“专业化覆盖常规模板,非模板 function 覆盖两者。” Why not just make a (regular) function for that use?为什么不为此用途制作一个(常规)function? Then a regular/non-template will override the template?那么常规/非模板将覆盖模板?

If my solution is correct, then what is a good example for Explicit Specialization?如果我的解决方案是正确的,那么显式专业化的一个很好的例子是什么?

One of the use case for explicit specialization is to avoid regular function to be skipped when some changes happens in the actual template function. 显式专业化的用例之一是避免在实际template函数中发生某些更改时跳过常规函数。 To understand see below example: 要了解,请参见以下示例:

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

Till now it's fine. 到现在为止还好。 Now after sometime you got to change the definition of template<> foo() 现在一段时间后,您必须更改template<> foo()的定义

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

You changed all the calls to foo() accordingly, but you missed/messed to change the regular overloaded function foo() . 您已相应地更改了对foo()所有调用,但是错过了/不得不更改常规重载函数foo() Then, it's a disaster ! 然后,这是一场灾难 Because compilation would go fine and regular calls would be silently replaced by the template<> foo() , which is undesired. 因为编译会很好并且常规调用将被template<> foo() 静默替换,所以这是不希望的。

Now, had there been an explicit specialization such as, 现在,是否有明确的专业化知识,例如,

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

then that function will give you compilation error due to unmatched parameters and which would remind you of corresponding changes. 则该函数会因参数不匹配而给您带来编译错误,并会提醒您相应的更改。

The other usage or (difference) is that an explicitly specialized function can be included in header file without any concern of multiple symbol linking error. 其他用法或(区别)是, 头文件中可以包含显式专门功能而无需担心多个符号链接错误。 Note that, explicit specialization has its own drabacks also, but I have demo a good side of it. 请注意,显式专业化也有其自身的特色,但我有一个很好的演示。

Why not just make a (regular) function for that use? 为什么不仅仅为此使用一个(常规)函数呢? Then a regular/non-template will override the template? 那么常规/非模板将覆盖模板?

Of course you can use regular function overload instead of explicit function template specialization if it is OK for you. 当然,如果可以的话,可以使用常规函数重载代替显式函数模板专门化。 But regular function overload will not be used if you explicitly use function template (by specifying template parameters). 但是,如果您显式使用函数模板(通过指定模板参数),则不会使用常规函数重载。

Example: 例:

You have function template: 您具有功能模板:

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

Then if you specify function overload: 然后,如果您指定函数重载:

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

In the code like this: 在这样的代码中:

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

function overload void foo( double& x, const double& y ) will never be used. 函数重载void foo( double& x, const double& y )将永远不会被使用。

But if you specify function template specialization 但是,如果指定功能模板专门化

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

Then some_function would use your specialization if you call 然后,如果调用, some_function将使用您的专业化

double x;

some_function(x);

somewhere. 某处。

Standard functions may be specialized but may not be overloaded, just for one example. 仅举例来说,标准功能可能是专门的,但可能不会过载。 Another example would be where the types are non-deducible and you have existing code which calls them with explicit template arguments- your overload is worthless then. 另一个例子是类型是不可推论的,而您已有的代码使用显式模板参数调用它们,那么重载就毫无价值了。

Another usage is to mark a special case of templated function as not callable.另一种用法是将模板化 function 的特例标记为不可调用。

template<typename T>
void processPointer(T* ptr);
template<>
void processPointer<void>(void*) = delete;
template<>
void processPointer<char>(char*) = delete;

(From Effective Modern C++ ) (来自Effective Modern C++

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM