簡體   English   中英

模板專門化/初始化和名稱空間?

[英]template specialization/initializations and namespaces?

關於模板專業化和名稱空間限定的C ++規則是什么? 我有一些代碼可以歸結為以下代碼,這使我意識到我不了解C ++有關模板專門化初始化的規則。 首先,對我來說似乎很奇怪,甚至在h內甚至允許g::F<>的專業化,但是鑒於此,我不知道事情為什么如此行事。

namespace g {

  struct N {
    N(char c):c_(c){}
    char c_;
  };

  template <typename V>
  struct F {
    static N n_s; // <-- want to initialize these for specializations
  };

  namespace h {
    struct X { static constexpr char k{'x'}; };

    template <> N F<char>::n_s{h::X::k};  // OK
    template <> N F<int>::n_s{X::k};      // fails on "‘X’ not declared"
  }
} // namespace g

// Seems weirdest to me. N and F need full qualifications but X doesn't.
template <> g::N g::F<float>::n_s{h::X::k}; // OK also!

最后一個實例化/初始化,其中模板靜態成員初始化器推斷g命名空間,使模板看起來好像模板起作用,就好像初始化器與模板定義本身位於代碼中的同一位置。

規范中規定此行為的規則是什么? (請注意,這已在gcc 4.8.1上進行了測試,到目前為止看起來有點像bug ...)

這里的主要困惑不是關於專業,而是關於資格。 讓我們看一下最后一個專門化(在全局名稱空間中)來說明這一點:

template <> g::N g::F<float>::n_s{h::X::k};

該行開始時,您位於全局名稱空間中。 因此, g::N一定是合格的, g::F<float>

但是,當您經過專門化的事物時(即在n_s之后),您現在就處在要進行專門化的事物的范圍內,即在g::F內部。 所有進一步的查找都在此范圍內完成,因此x必須限定為h::X

就是說,雖然允許在包圍原始名稱空間的名稱空間中對事物進行特殊化,但對嵌套名稱空間(在您的情況下為h進行特殊化對我來說似乎很奇怪,但此處的標准有點含糊,如14.7.3 / 2:“顯式專門化應在包含專門化模板的命名空間中聲明。”

全局名稱空間用F包圍,所以很好, g h不包含F ,但是hg內,因此專業化也在g內,從技術上講,這很好。 但是,通過這種推理,您可以絕對在任何地方對模板進行專業化處理,因為您始終位於全局名稱空間中,該名稱空間將所有內容都包含在內。 因此,我很確定GCC在這里的行為過於寬松,並且存在錯誤。 您也應該與其他編譯器一起嘗試此操作,然后提交一個錯誤,或者根據標准提交缺陷報告。

在:

template <> N F<int>::n_s{X::k};      // fails on "‘X’ not declared"

它失敗是因為與F<int>::n_s關聯的命名空間是g ,而Xg::h聲明。 這就是為什么您需要像h::F<int>::n_s這樣拼寫出來的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM