久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

C++ 模板函數重載解析

C++ template functions overload resolution(C++ 模板函數重載解析)
本文介紹了C++ 模板函數重載解析的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

我有以下代碼:

#include 模板 void f (T) { std::cout <<f(T)"<<std::endl;}模板 void f (bool) { std::cout <<"f(bool)" <<std::endl;}內部主(){f(真);//#1 打印 f(T)f<bool>(真);//#2 打印 f(bool)}

#1 行調用 f(T),而 #2 行調用 f(bool).

為什么會這樣?以及選擇重載模板函數的規則是什么?

更新

我知道在第一次調用中,編譯器在嘗試調用第二個函數時無法推斷出T,所以選擇了第一個.

在第二次調用中,第二個函數被認為在 gcc 上更匹配,而第一個是在 VS2013 下選擇的.誰在這里做正確的事?順便說一句,我仍然對過程的完整描述感興趣.

解決方案

未特化的函數模板也稱為底層基模板. 基模板可以是特化的.查看在不同情況下調用哪些方法的重載規則非常簡單,至少在高層次上是這樣:

  • 非模板函數是一等公民.與參數類型以及任何函數模板匹配的普通舊非模板函數將被選擇,而不是其他一樣好的函數模板.

  • 如果沒有至少與二等公民一樣好的一等公民可供選擇,那么接下來將咨詢二等公民的函數基礎模板.根據一組相當神秘規則:

    • 如果很明顯有一個最專業的"函數基礎模板,那么就會使用那個模板.如果該基模板恰好專用于正在使用的類型,則將使用該特化,否則將使用使用正確類型實例化的基模板.

    • Else(如您的情況)如果最專業"的函數基模板存在聯系,則調用是不明確的,因為編譯器無法決定哪個更匹配.程序員必須做一些事情來限定調用并說明需要哪個.

    • 否則,如果沒有可以匹配的函數基礎模板,調用就會出錯,程序員將不得不修復代碼.

如果您想自定義函數基礎模板并希望該自定義參與重載解析(或者,始終在完全匹配的情況下使用),請將其設為普通的舊函數,不是專業.而且,如果您確實提供了重載,請避免同時提供專業化.

以上摘自the Herb Sutter,在突出顯示的項目符號中,您可以看到問題的根源

編輯

如果你在 Visual Studio 2012 中嘗試(不要這樣做)上面的代碼,你會得到 <塊引用>

致命錯誤 LNK1179:無效或損壞的文件:重復的 COMDAT '??$f@_N@@YAX_N@Z'

正如此處所解釋的那樣,是因為

<塊引用>

你做了一些 C++ 無效的詭計",它通過了編譯器,但你現在有一個無效的 *.obj,它阻塞了鏈接器.

下面這行是罪魁禍首

f(true);//#1 打印 f(T)

所以答案中解釋的歧義沒有保證解決

I have the following code:

#include <iostream>

template <typename T>
void f (T) { std::cout << "f(T)" << std::endl; }

template <typename T>
void f (bool) { std::cout << "f(bool)" << std::endl; }

int main ( )
{
    f(true);        // #1 prints f(T)
    f<bool>(true);  // #2 prints f(bool)
}

The #1 line calls f(T), while #2 line calls f(bool).

Why does this happen? And what are the rules for selecting an overloaded template function?

UPDATE

I understood that in the first call compiler is just unable to deduce T while trying to call the second function, so the first is chosen.

In the second call second function is considered a better match on gcc, while the first is chosen under VS2013. Who does the right thing here? By the way, I am still interested in the full description of the process.

解決方案

The unspecialized function templates are also called the underlying base templates. Base templates can be specialized. The overloading rules to see which ones get called in different situations, are pretty simple, at least at a high level:

  • Nontemplate functions are first-class citizens. A plain old nontemplate function that matches the parameter types as well as any function template will be selected over an otherwise-just-as-good function template.

  • If there are no first-class citizens to choose from that are at least as good, then function base templates as the second-class citizens get consulted next. Which function base template gets selected depends on which matches best and is the "most specialized" (important note: this use of "specialized" oddly enough has nothing to do with template specializations; it's just an unfortunate colloquialism) according to a set of fairly arcane rules:

    • If it's clear that there's one "most specialized" function base template, that one gets used. If that base template happens to be specialized for the types being used, the specialization will get used, otherwise the base template instantiated with the correct types will be used.

    • Else (as in your case) if there's a tie for the "most specialized" function base template, the call is ambiguous because the compiler can't decide which is a better match. The programmer will have to do something to qualify the call and say which one is wanted.

    • Else if there's no function base template that can be made to match, the call is bad and the programmer will have to fix the code.

If you want to customize a function base template and want that customization to participate in overload resolution (or, to always be used in the case of exact match), make it a plain old function, not a specialization. And, if you do provide overloads, avoid also providing specializations.

The above is an extract from this post by the Herb Sutter and in the highlighted bullet you can see the source of your problem

EDIT

If you try (don't do it) the above code with Visual Studio 2012, you get

fatal error LNK1179: invalid or corrupt file: duplicate COMDAT '??$f@_N@@YAX_N@Z'

which, as explained here, is because

You did some "trickery" that is invalid C++, and it passed the compiler, but you now have an invalid *.obj, and it chokes the linker.

and the following line is to blame

f(true);        // #1 prints f(T)

so the ambiguity explained in the answer has no guarandeed resolution

這篇關于C++ 模板函數重載解析的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Difference between std::reference_wrapper and simple pointer?(std::reference_wrapper 和簡單指針的區別?)
Difference between const. pointer and reference?(常量之間的區別.指針和引用?)
How to access the contents of a vector from a pointer to the vector in C++?(c++ - 如何從指向向量的指針訪問向量的內容?)
Meaning of *amp; and **amp; in C++(*amp; 的含義和**amp;在 C++ 中)
Why can#39;t I do polymorphism with normal variables?(為什么我不能對普通變量進行多態?)
Dereferencing deleted pointers always result in an Access Violation?(取消引用已刪除的指針總是會導致訪問沖突?)
主站蜘蛛池模板: 久久精品一区 | www.性色| 男人的天堂久久 | 97国产超碰 | 国产成人精品一区二区三 | 国产精品国产三级国产aⅴ中文 | 欧美日韩不卡合集视频 | 亚洲视频在线播放 | 亚洲不卡在线观看 | 亚洲欧洲在线观看视频 | 欧美a级成人淫片免费看 | 久久88| 久久专区 | 日批日韩在线观看 | 99精品欧美一区二区三区 | 亚洲a在线观看 | 久久精品无码一区二区三区 | 国产伊人久久久 | 欧美激情综合五月色丁香小说 | 国外成人在线视频网站 | 一区二区亚洲 | 国产日韩欧美在线 | 亚洲天堂一区 | 色又黄又爽网站www久久 | 精品久久网| 欧美激情一区二区三区 | 免费一区二区三区 | 羞羞的视频免费看 | 日韩小视频 | 国产视频久久久 | 亚洲精品久久久久久一区二区 | 国产无套一区二区三区久久 | 亚洲欧美自拍偷拍视频 | 亚洲精品国产区 | 久久99蜜桃综合影院免费观看 | 成人性视频免费网站 | 51ⅴ精品国产91久久久久久 | 国产精品久久久久婷婷二区次 | 涩涩视频在线观看 | 精品视频一区二区在线观看 | 国产成人精品a视频 |