繁体   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