pos機(jī)設(shè)計(jì)模板

 新聞資訊2  |   2023-07-07 08:09  |  投稿人:pos機(jī)之家

網(wǎng)上有很多關(guān)于pos機(jī)設(shè)計(jì)模板,C++ 函數(shù)模板特化和類模板特化的知識(shí),也有很多人為大家解答關(guān)于pos機(jī)設(shè)計(jì)模板的問(wèn)題,今天pos機(jī)之家(m.afbey.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來(lái)看下吧!

本文目錄一覽:

1、pos機(jī)設(shè)計(jì)模板

pos機(jī)設(shè)計(jì)模板

我們知道,一種數(shù)據(jù)類型總是對(duì)應(yīng)一個(gè)特定的操作集,使用一個(gè)特定的運(yùn)算符集合。當(dāng)函數(shù)模板和類模板實(shí)例化時(shí),模板定義的一系列操作并不一定適合所有的預(yù)定義類型。

1 函數(shù)模板特化 Function template specialization

When instantiating a function template for a given type, the compiler stencils out a copy of the templated function and replaces the template type parameters with the actual types used in the variable declaration. This means a particular function will have the same implementation details for each instanced type (just using different types). While most of the time, this is exactly what you want, occasionally there are cases where it is useful to implement a templated function slightly different for a specific data type.

當(dāng)為給定類型實(shí)例化函數(shù)模板時(shí),編譯器會(huì)制作模板化函數(shù)的副本,并用變量聲明中使用的實(shí)際類型替換模板類型參數(shù)。這意味著對(duì)于每個(gè)實(shí)例類型,特定函數(shù)將具有相同的實(shí)現(xiàn)細(xì)節(jié)(只是使用不同的類型)。雖然在大多數(shù)情況下,這正是您想要的,但偶爾也有一些情況下,實(shí)現(xiàn)與特定數(shù)據(jù)類型略有不同的模板化函數(shù)很有用。

Template specialization is one way to accomplish this.

模板專門(mén)化是實(shí)現(xiàn)這一點(diǎn)的一種方法。

template <typename T>class Storage{private: T m_value {};public: Storage(T value) : m_value { value } { } void print() { std::cout << m_value << '\'; }};

Now, let’s say we want double values (and only double values) to output in scientific notation. To do so, we can use a function template specialization (sometimes called a full or explicit function template specialization) to create a specialized version of the print() function for type double. This is extremely simple: simply define the specialized function (if the function is a member function, do so outside of the class definition), replacing the template type with the specific type you wish to redefine the function for. Here is our specialized print() function for doubles:

現(xiàn)在,讓我們假設(shè)我們希望以科學(xué)記數(shù)法輸出雙精度值(并且只有雙精度值)。為此,我們可以使用函數(shù)模板特化(有時(shí)稱為完整或顯式函數(shù)模板特化)為類型double創(chuàng)建print()函數(shù)的專門(mén)化版本。這非常簡(jiǎn)單:只需定義專門(mén)化函數(shù)(如果函數(shù)是成員函數(shù),則在類定義之外進(jìn)行定義),將模板類型替換為要為其重新定義函數(shù)的特定類型。下面是專門(mén)用于doubles的print()函數(shù):

template <>void Storage<double>::print(){ std::cout << std::scientific << m_value << '\';}

When the compiler goes to instantiate Storage<double>::print(), it will see we’ve already explicitly defined that function, and it will use the one we’ve defined instead of stenciling out a version from the generic templated class.

當(dāng)編譯器實(shí)例化Storage<double>::print()時(shí),它將看到我們已經(jīng)顯式定義了該函數(shù),并且它將使用我們定義的函數(shù),而不是從通用模板類中打印出版本。

The template <> tells the compiler that this is a template function, but that there are no template parameters (since in this case, we’re explicitly specifying all of the types). Some compilers may allow you to omit this, but it’s correct to include it.

template <>告訴編譯器這是一個(gè)模板函數(shù),但沒(méi)有模板參數(shù)(因?yàn)樵诒纠校覀冿@式指定了所有類型)。某些編譯器可能允許您省略這一點(diǎn),但包含它是正確的。

2 類模板特化 Class Template Specialization

In many cases when working with templates, you'll write one generic version for all possible data types and leave it at that--every vector may be implemented in exactly the same way. The idea of template specialization is to override the default template implementation to handle a particular type in a different way.For instance, while most vectors might be implemented as arrays of the given type, you might decide to save some memory and implement vectors of bools as a vector of integers with each bit corresponding to one entry in the vector. So you might have two separate vector classes.

在許多情況下,在使用模板時(shí),您將為所有可能的數(shù)據(jù)類型編寫(xiě)一個(gè)通用版本,并將其保留在該版本中--每個(gè)向量都可以用完全相同的方式實(shí)現(xiàn)。模板特化的思想是重寫(xiě)默認(rèn)模板實(shí)現(xiàn),以不同的方式處理特定類型。例如,雖然大多數(shù)向量可能實(shí)現(xiàn)為給定類型的數(shù)組,但您可能會(huì)決定保存一些內(nèi)存,并將布爾向量實(shí)現(xiàn)為整數(shù)向量,每個(gè)位對(duì)應(yīng)于向量中的一個(gè)條目。所以你可能有兩個(gè)獨(dú)立的向量類。

template <typename T>class vector{ // accessor functions and so forthprivate: T* vec_data; // we'll store the data as block of dynamically allocated // memory int length; // number of elements used int vec_size; // actual size of vec_data};

But when it comes to bools, you might not really want to do this because most systems are going to use 16 or 32 bits for each boolean type even though all that's required is a single bit. So we might make our boolean vector look a little bit different by representing the data as an array of integers whose bits we manually manipulate.

但當(dāng)涉及布爾值時(shí),您可能并不真正想要這樣做,因?yàn)榇蠖鄶?shù)系統(tǒng)將為每個(gè)布爾值類型使用16或32位,即使只需要一個(gè)位。因此,我們可以通過(guò)將數(shù)據(jù)表示為一個(gè)整數(shù)數(shù)組,手動(dòng)操作其位,從而使布爾向量看起來(lái)有點(diǎn)不同。

To do this, we still need to specify that we're working with something akin to a template, but this time the list of template parameters will be empty:

為此,我們?nèi)匀恍枰付ㄕ谑褂妙愃朴谀0宓膬?nèi)容,但這次模板參數(shù)列表將為空:

template <>

and the class name is followed by the specialized type: class className<type>. In this case, the template would look like this:

類名后面緊跟著專用類型:class className<type>。在這種情況下,模板如下所示:

template <>class vector <bool>{ // interfaceprivate: unsigned int *vector_data; int length; int size;};

Note that it would be perfectly reasonable if the specialized version of the vector class had a different interface (set of public methods) than the generic vector class--although they're both vector templates, they don't share any interface or any code.

請(qǐng)注意,如果vector類的專用版本具有與通用vector類不同的接口(公共方法集),這將是完全合理的——盡管它們都是向量模板,但它們不共享任何接口或代碼。

It's worth pointing out that the salient reason for the specialization in this case was to allow for a more space-efficient implementation, but you could think of other reasons why this might come in handy--for instance, if you wanted to add extra methods to one templated class based on its type, but not to other templates.

值得指出的是,在這種情況下進(jìn)行專門(mén)化的主要原因是為了實(shí)現(xiàn)更節(jié)省空間的實(shí)現(xiàn),但您可以考慮其他原因來(lái)說(shuō)明這一點(diǎn)——例如,如果您想根據(jù)一個(gè)模板類的類型向其添加額外的方法,而不是向其他模板添加額外的方法。

For instance, you might have a vector of doubles with a method that returns the non-integer component of each element although you might think prefer inheritance in this case. There isn't a particular reason to prevent the existence of a vector of doubles without those extra features. If, however, you felt strongly about the issue and wanted to prevent it, you could do so using template specialization.

例如,您可能有一個(gè)double向量,其中一個(gè)方法返回每個(gè)元素的非整數(shù)部分,盡管在這種情況下您可能認(rèn)為更喜歡繼承。沒(méi)有什么特別的理由可以阻止沒(méi)有這些額外特征的雙向量的存在。然而,如果您對(duì)這個(gè)問(wèn)題有強(qiáng)烈的感覺(jué)并想阻止它,那么可以使用模板專門(mén)化來(lái)做到這一點(diǎn)。

Another time when you might want to specialize certain templates could be if you have a template type that relies on some behavior that was not implemented in a collection of classes you'd like to store in that template.

另一種可能需要專門(mén)化某些模板的情況是,如果您的模板類型依賴于某些行為,而這些行為沒(méi)有在要存儲(chǔ)在該模板中的類集合中實(shí)現(xiàn)。

For example, if you had a templated sortedVector type that required the > operator to be defined, and a set of classes written by someone else that didn't include any overloaded operators but did include a function for comparison, you might specialize your template to handle these classes separately.

例如,如果您有一個(gè)模板化的sortedVector類型,需要定義>操作符,并且有一組由其他人編寫(xiě)的類,其中不包含任何重載操作符,但包含一個(gè)用于比較的函數(shù),那么您可以專門(mén)化模板來(lái)分別處理這些類。

3 類模板偏特化 Class Template Partial Specialization

Partial template specialization stems from similar motives as full specialization as described above. This time, however, instead of implementing a class for one specific type, you end up implementing a template that still allows some parameterization. That is, you write a template that specializes on one feature but still lets the class user choose other features as part of the template. Let's make this more concrete with an example.

模板偏特化源于與上述完全特化類似的動(dòng)機(jī)。然而,這次不是為一個(gè)特定類型實(shí)現(xiàn)一個(gè)類,而是實(shí)現(xiàn)了一個(gè)仍然允許一些參數(shù)化的模板。也就是說(shuō),您編寫(xiě)的模板專門(mén)針對(duì)一個(gè)功能,但仍然允許類用戶選擇其他功能作為模板的一部分。讓我們用一個(gè)例子來(lái)說(shuō)明這一點(diǎn)。

Going back to the idea of extending the concept of vectors so that we can have a sortedVector, let's think about how this might look: we'll need a way of making comparisons. Fine; we can just use > if it's been implemented, or specialize if it hasn't. But now let's say that we wanted to have pointers to objects in our sorted vector. We could sort them by the value of the pointers, just doing a standard > comparison (we'll have a vector sorted from low to high):

回到擴(kuò)展向量概念的想法,這樣我們就可以有一個(gè)sortedVector,讓我們思考一下它的外觀:我們需要一種進(jìn)行比較的方法。如果已經(jīng)實(shí)現(xiàn),我們可以直接使用大于號(hào)>,如果還沒(méi)有實(shí)現(xiàn),則可以特化。但現(xiàn)在讓我們假設(shè)我們希望在排序向量中有指向?qū)ο蟮闹羔?。我們可以根?jù)指針的值對(duì)它們進(jìn)行排序,只需執(zhí)行標(biāo)準(zhǔn)>比較(我們將有一個(gè)從低到高排序的向量):

template <typename T>class sortedVector{public: void insert (T val) { if( length == vec_size ) // length is the number of elements { vec_size *= 2; // we'll just ignore overflow possibility! vec_data = new T[vec_size]; } ++length; // we are about to add an element // we'll start at the end, sliding elements back until we find the // place to insert the new element int pos; for( pos = length; pos > 0 && val > vec_data[pos - 1]; --pos ) { vec_data[pos] = vec_data[pos - 1]; } vec_data[pos] = val; } // other functions...private: T *vec_data; int length; int size;};

Now, notice that in the above for loop, we're making a direct comparison between elements of type T. That's OK for most things, but it would probably make more sense to have sorted on the actual object type instead of the pointer address. To do that, we'd need to write code that had this line:

現(xiàn)在,請(qǐng)注意,在上面的for循環(huán)中,我們對(duì)T類型的元素進(jìn)行了直接比較。大多數(shù)情況下都可以,但按實(shí)際對(duì)象類型而不是指針地址排序可能更有意義。為此,我們需要編寫(xiě)具有以下行的代碼:

for( pos = length; pos > 0 && *val > *vec_data[pos - 1]; --pos )

Of course, that would break for any non-pointer type. What we want to do here is use a partial specialization based on whether the type is a pointer or a non-pointer (you could get fancy and have multiple levels of pointers, but we'll stay simple).To declare a partially specialized template that handles any pointer types, we'd add this class declaration:

當(dāng)然,對(duì)于任何非指針類型,這都是錯(cuò)誤的。這里我們要做的是根據(jù)類型是指針還是非指針使用偏特化(您可能會(huì)有很多級(jí)別的指針,但我們會(huì)保持簡(jiǎn)單)。要聲明處理任何指針類型的偏(部分)特化模板,我們將添加以下類聲明:

template <typename T>class sortedVector<T *>{public:// same functions as before. Now the insert function looks like this: insert( T *val ) { if( length == vec_size ) // length is the number of elements { vec_size *= 2; // we'll just ignore overflow possibility! vec_data = new T[vec_size]; } ++length; // we are about to add an element // we'll start at the end, sliding elements back until we find the // place to insert the new element int pos; for( pos = length; pos > 0 && *val > *vec_data[pos - 1]; --pos ) { vec_data[pos] = vec_data[pos - 1]; } vec_data[pos] = val; }private: T** vec_data; int length; int size;};

There are a couple of syntax points to notice here. First, our template parameter list still names T as the parameter, but the declaration now has a T * after the name of the class; this tells the compiler to match a pointer of any type with this template instead of the more general template. The second thing to note is that T is now the type pointed to; it isnotitself a pointer.

這里有幾個(gè)語(yǔ)法點(diǎn)需要注意。首先,我們的模板參數(shù)列表仍然將T命名為參數(shù),但聲明現(xiàn)在在類名稱后有一個(gè)T*;這告訴編譯器將任何類型的指針與此模板匹配,而不是與更一般的模板匹配。第二點(diǎn)需要注意的是,T現(xiàn)在是所指的類型;它本身不是指針。

For instance, when you declare a sortedVector<int *>, T will refer to the int type! This makes some sense if you think of it as a form of pattern matching where T matches the type if that type is followed by an asterisk. This does mean that you have to be a tad bit more careful in your implementation: note that vec_data is a T** because we need a dynamically sized array made up of pointers.

例如,當(dāng)您聲明sortedVector時(shí),T將引用int類型!如果您將其視為一種模式匹配形式,其中T與類型匹配,如果該類型后跟一個(gè)星號(hào),那么這就有一定的意義。這確實(shí)意味著您在實(shí)現(xiàn)時(shí)必須更加小心:請(qǐng)注意,vec_data是一個(gè)T**,因?yàn)槲覀冃枰粋€(gè)由指針組成的動(dòng)態(tài)大小的數(shù)組。

You might wonder if you really want your sortedVector type to work like this--after all, if you're putting them in an array of pointers, you'd expect them to be sorted by pointer type. But there's a practical reason for doing this: when you allocate memory for an array of objects, the default constructor must be called to construct each object. If no default constructor exists (for instance, if every object needs some data to be created), you're stuck needing a list of pointers to objects, but you probably want them to be sorted the same way the actual objects themselves would be!

您可能想知道您是否真的希望sortedVector類型像這樣工作——畢竟,如果您將它們放在指針數(shù)組中,您希望它們按指針類型排序。但這樣做有一個(gè)實(shí)際原因:當(dāng)您為對(duì)象數(shù)組分配內(nèi)存時(shí),必須調(diào)用默認(rèn)構(gòu)造函數(shù)來(lái)構(gòu)造每個(gè)對(duì)象。如果不存在默認(rèn)構(gòu)造函數(shù)(例如,如果每個(gè)對(duì)象都需要?jiǎng)?chuàng)建一些數(shù)據(jù)),那么您就需要一個(gè)指向?qū)ο蟮闹羔樍斜?,但您可能希望它們的排序方式與實(shí)際對(duì)象本身的排序方式相同!

Note, by the way, that you can also partially specialize on template arguments--for instance, if you had a fixedVector type that allowed the user of the class to specify both a type to store and the length of the vector (possibly to avoid the cost of dynamic memory allocations), it might look something like this:

順便注意,您還可以偏特化模板參數(shù)——例如,如果您有一個(gè)fixedVector類型,該類型允許類的用戶指定要存儲(chǔ)的類型和向量的長(zhǎng)度(可能是為了避免動(dòng)態(tài)內(nèi)存分配的開(kāi)銷),那么它可能如下所示:

template <typename T, unsigned length>class fixedVector { ... };

Then you could partially specialize for booleans with the following syntax

然后可以使用以下語(yǔ)法部分專門(mén)化布爾值

template <unsigned length>class fixedVector<bool, length> {...}

Note that since T is no longer a template parameter, it's left out of the template parameter list, leaving only length. Also note that length now shows up as part of fixedVector's name (unlike when you have a generic template declaration, where you specify nothing after the name). (By the way, don't be surprised to see a template parameter that's a non-type: it's perfectly valid, and sometimes useful, to have template arguments that are integer types such as unsigned.)

請(qǐng)注意,因?yàn)門(mén)不再是模板參數(shù),所以它被排除在模板參數(shù)列表之外,只留下長(zhǎng)度。還要注意,長(zhǎng)度現(xiàn)在顯示為fixedVector名稱的一部分(不同于使用通用模板聲明時(shí),在名稱后不指定任何內(nèi)容)。(順便說(shuō)一句,看到一個(gè)非類型的模板參數(shù)不要感到驚訝:如果模板參數(shù)是整數(shù)類型,例如無(wú)符號(hào)的,那么它是完全有效的,有時(shí)也是有用的。)

A final implementation detail comes up with partial specializations: how does the compiler pick which specialization to use if there are a combination of completely generic types, some partial specializations, and maybe even some full specializations? The general rule of thumb is that the compiler will pick the most specific template specialization--the most specific template specialization is the one whose template arguments would be accepted by the other template declarations, but which would not accept all possible arguments that other templates with the same name would accept.

最后一個(gè)實(shí)現(xiàn)細(xì)節(jié)是偏特化:如果存在完全泛型類型、一些部分特化甚至一些完全特化的組合,編譯器如何選擇要使用的特化?一般的經(jīng)驗(yàn)法則是編譯器將選擇最具體的模板特化——最具體的模板特化是其模板參數(shù)將被其他模板聲明接受,但不會(huì)接受其他同名模板將接受的所有可能參數(shù)的模板特化。

For instance, if you decided that you wanted a sortedVector<int *> that sorted by memory location, you could create a full specialization of sortedVector and if you declared a sortedVector<int *>, then the compiler would pick that implementation over the less-specific partial specialization for pointers. It's the most specialized since only an int * matches the full specialization, not any other pointer type such as a double *, whereas int * certainly could be a parameter to either of the other templates.

例如,如果您決定需要一個(gè)按內(nèi)存位置排序的sortedVector,則可以創(chuàng)建sortedVector的完全特化,如果您聲明了sortedVector,則編譯器將選擇該實(shí)現(xiàn),而不是指針的不太具體的偏特化。它是最專業(yè)化的,因?yàn)橹挥衖nt*匹配完全特化,而不是任何其他指針類型,如double*,而int*當(dāng)然可以是其他模板的參數(shù)。

ref

https://www.learncpp.com/cpp-tutorial/function-template-specialization/

https://www.cprogramming.com/tutorial/template_specialization.html

以上就是關(guān)于pos機(jī)設(shè)計(jì)模板,C++ 函數(shù)模板特化和類模板特化的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于pos機(jī)設(shè)計(jì)模板的知識(shí),希望能夠幫助到大家!

轉(zhuǎn)發(fā)請(qǐng)帶上網(wǎng)址:http://m.afbey.com/newsone/80883.html

你可能會(huì)喜歡:

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 babsan@163.com 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。