亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

SFINAE適用的C ++ 11標準中提到的“即時上下文”到底是什么?

SFINAE適用的C ++ 11標準中提到的“即時上下文”到底是什么?

C++
函數式編程 2019-09-26 10:30:46
C ++ 11標準的14.8.2 / 8段規定了替換失敗應或不應該導致“硬”編譯錯誤(從而導致編譯失敗)或“軟”錯誤的條件,使編譯器從一組候選集中丟棄模板以進行重載解決(而不會使編譯失敗并啟用眾所周知的SFINAE慣用語):如果替換導致無效的類型或表達式,則類型推導將失敗。無效的類型或表達式是使用替換參數編寫的格式或表達式。[注意:訪問檢查是替代過程的一部分?!?—注釋[end note] 只有在函數類型及其模板參數類型的直接上下文中無效的類型和表達式才可能導致推論失敗。[...]在整個C ++ 11標準中,“ 即時上下文 ”一詞僅出現8次,并且每次其后跟隨(或作為其一部分)以下(非規范)文本的實例:[注:對替換類型和表達式的求值可能會導致副作用,例如實例化類模板專業化和/或函數模板專業化,生成隱式定義的函數等。此類副作用不在“立即”中。上下文”,并可能導致程序格式錯誤?!沧該注釋對即時上下文的含義給出了(不是很慷慨的)提示,但至少對我而言,這通常不足以確定獨占是否會導致“硬”編譯錯誤。題:您能否提供說明,決策過程和/或一些具體示例,以幫助弄清楚在什么情況下函數類型及其模板參數類型的“ 立即上下文 ”中發生或不發生替代錯誤?
查看完整描述

2 回答

?
白板的微信

TA貢獻1883條經驗 獲得超3個贊

直接背景基本上是什么,你在模板聲明本身看到的。除此之外的一切都是硬錯誤。硬錯誤示例:

#include <type_traits>template<class T>struct trait{ using type = typename T::type; };template<class T, class U = typename trait<T>::type>void f(int);void f(...);template<class T, class U = typename T::type>void g(int);void g(...);template<class>struct dependent_false : std::false_type{};template<class T>struct X{
    static_assert(dependent_false<T>(), "...");
    using type = void;};int main(){
    f<int>(0);
    g<X<int>>(0);}

現場版。


查看完整回答
反對 回復 2019-09-26
?
哈士奇WWW

TA貢獻1799條經驗 獲得超6個贊

如果您考慮了確定模板參數替換結果所需的所有模板和隱式定義的函數,并假設它們是在替換開始之前首先生成的,則在第一步中發生的任何錯誤都不會立即出現,并導致硬錯誤。

如果所有這些實例化和隱式定義(可能包括將函數定義為已刪除)都可以正確執行,那么替換期間(即在引用函數模板的實例化模板和隱式定義函數時)會發生任何其他“錯誤”。簽名)不是錯誤,但會導致推理失敗。

因此,給定這樣的功能模板:

template<typename T>voidfunc(typename T::type* arg);

以及在其他功能的推論失敗時將使用的“后備”:

template<typename>voidfunc(...);

和這樣的類模板:

template<typename T>
  struct A  {
    typedef T* type;
  };

調用func<A<int&>>(nullptr)將替代A<int&>,T并且為了檢查是否T::type存在,必須實例化A<int&>。如果我們設想在調用之前放一個顯式實例化func<A<int&>(nullptr)

template class A<int&>;

那么這將失敗,因為它嘗試創建類型int&*并且不允許使用指向引用的指針。我們沒有到檢查替換是否成功的地步,因為實例化存在一個嚴重的錯誤A<int&>

現在,我們有一個明確的專業化A

template<>
  struct A<char>
  {
  };

對的調用func<A<char>>(nullptr)需要實例化A<char>,因此請想象在調用之前程序中某個地方的顯式實例化:

template class A<char>;

此實例化還可以,沒有任何錯誤,因此我們繼續進行參數替換。work的實例化A<char>,但A<char>::type不存在,但是可以,因為它僅在的聲明中引用func,因此只會導致參數推導失敗,而...將調用后備功能。

在其他情況下,替換可能導致特殊成員函數被隱式定義(可能已刪除),這可能會觸發其他實例化或隱式定義。如果在“生成實例和隱式定義”階段發生錯誤,那么它們就是錯誤,但是如果成功但在替換期間發生錯誤,則函數模板簽名中的表達式將變為無效,例如,因為它使用的成員不存在或被隱式定義為刪除的東西,這不是錯誤,只是推論失敗。

因此,我使用的思維模型是,替換需要首先執行“準備”步驟才能生成類型和成員,這可能會導致嚴重錯誤,但是一旦我們完成了所有必要的生成,任何進一步的無效使用就不會出錯。當然,這一切都是將問題從“ 即時上下文是什么意思?” 移開。“在檢查此替換之前需要生成哪些類型和成員?” 因此它可能會或可能不會幫助您!


查看完整回答
反對 回復 2019-09-26
  • 2 回答
  • 0 關注
  • 768 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號