C++ 为什么允许嵌套类模板的部分专门化,而完整的则是isn';T 模板结构A{ 模板结构B{};。 模板结构C{}; }; 模板 结构A::B{};//错误:封闭类模板未显式专用 模板 结构A::C{};//好啊

C++ 为什么允许嵌套类模板的部分专门化,而完整的则是isn';T 模板结构A{ 模板结构B{};。 模板结构C{}; }; 模板 结构A::B{};//错误:封闭类模板未显式专用 模板 结构A::C{};//好啊,c++,templates,metaprogramming,C++,Templates,Metaprogramming,那么,如果外部类不是专门化的,为什么不允许显式专门化内部嵌套类(或函数)?奇怪的是,如果我只通过简单地添加一个伪模板参数来部分地专门化内部类,我就可以解决这个问题。使事情变得更加丑陋和复杂,但它是有效的 我认为完整的专业化是部分专业化的一个子集,尤其是因为您可以通过添加一个哑参数来表示每个完全专业化作为一个部分。所以,在部分专业化和完全专业化之间消除歧义对我来说没有意义 不幸的是,没有人敢回答这个问题,所以我又把它放在这里了。 注意:对于一组外部类的内部类的递归模板,我需要此功能,并且内部参数的

那么,如果外部类不是专门化的,为什么不允许显式专门化内部嵌套类(或函数)?奇怪的是,如果我只通过简单地添加一个伪模板参数来部分地专门化内部类,我就可以解决这个问题。使事情变得更加丑陋和复杂,但它是有效的

我认为完整的专业化是部分专业化的一个子集,尤其是因为您可以通过添加一个哑参数来表示每个完全专业化作为一个部分。所以,在部分专业化和完全专业化之间消除歧义对我来说没有意义

不幸的是,没有人敢回答这个问题,所以我又把它放在这里了。
注意:对于一组外部类的内部类的递归模板,我需要此功能,并且内部参数的专门化确实取决于外部模板参数。

C++标准明确禁止在第一种情况下完全专门化成员模板类。根据14.7.3/18:

在类模板或出现的成员模板的成员的显式专门化声明中 在名称空间范围内,成员模板及其某些封闭类模板可能未被专门化, 除非声明不应显式地专门化类成员模板,如果它是封闭类 模板也没有明确专门化


我猜测为什么会发生这种情况:完全的专门化不再是“模板类/函数”,它们是“真实的”类/方法,并且得到了真实的(链接器可见)符号。但对于一个完全专门化的模板和一个部分专门化的模板,这是不正确的。
也许这个决定只是为了简化编译器编写者的生活(并且让程序员的生活变得更困难,在这个过程中:P)。< /P> < P>备份维吉尔的论点(他比我发布相同的理由快),考虑一下:

    template<int x> struct A {                                                                                                    
        template<int y> struct B {};.                                                                                             
        template<int y, int unused> struct C {};                                                                                  
    };                                                                                                                            

    template<int x> template<> 
    struct A<x>::B<x> {}; // error: enclosing class templates are not explicitly specialized

    template<int x> template<int unused> 
    struct A<x>::C<x, unused> {}; // ok
模板
阶级吹捧者
{
公众:
模板
分级镀锡机
{
公众:
T1μ1;
T2μ2;
};
};
模板
模板
类吹捧者:TInner
{
公众:
T1μ1;
浮动m_2;
};
TInner是完全专业化还是部分专业化是因为T1

编辑:

在考虑了其他一些注释之后,您似乎希望基于外部类中的模板参数进行完全专门化。如果嵌套内部类的实现,这在Visual Studio 2005中似乎是可行的:

template<typename T1>
class TOuter
  {
  public:
    template<typename T2>
    class TInner
      {
      public:
        T1 m_1;
        T2 m_2;
      };
  };

template<typename T1>
template<>
class TOuter<T1>::TInner<float>
  {
  public:
    T1    m_1;
    float m_2;
 };
模板
阶级吹捧者
{
公众:
模板
分级镀锡机
{
公众:
std::string DoSomething(){return“Inner-general”;}
T2μ2;
};
模板
分级镀锡机
{
公众:
std::string DoSomething(){返回“内部-特殊”;}
T1μ1;
};
};

TOuter::TInner将正确地成为TInner的专业化。我无法使用模板之外的实现进行编译。

您可以通过将实际工作委托给另一个结构来解决此问题:

template<typename T1>
class TOuter
  {
  public:
    template<typename T2>
    class TInner
      {
      public:
        std::string DoSomething() { return "Inner - general"; }
        T2 m_2;
      };

    template<>
    class TInner<T1>
      {
      public:
        std::string DoSomething() { return "Inner - special"; }
        T1 m_1;
      };
  };
名称空间详细信息
{
模板
结构InnerImpl{};
}
模板
结构外部
{
模板
结构内部:详细信息::InnerImpl
{
};
};

现在您可以根据自己的意愿专门化
inneimpl

这不是我问题的答案。如果您阅读了我的问题,您会注意到我已经知道嵌套类的显式专门化是不允许的。我已经找到了规避禁令的方法。我的问题是为什么这样做?只有C++标准的创造者才真正知道为什么会这样。“只有C++标准的创造者才真正知道为什么会这样”——你为什么这么说?C++标准是通过开放的过程开发的,许多决策在公众中进行了辩论:在邮件列表或新闻组,在会议上。此外,Stroustrup已经写了一本关于C++背后的设计决策的书。您是否检查过没有关于这个特定决定的可用信息,或者这是一个关于任何人都可以“真正了解”任何事情的哲学论点?;-)语言设计不是一个“专家”走进的黑匣子,标准是出来的。史提夫,“C++标准是通过一个开放的过程发展的”,利特布:是的,如果在早期,安德鲁·克尼格和Bjarne Stroustrup在电梯里相遇,而没有人花分钟,那么谁知道黑暗交易可能是怎么做的。我的观点不是C++完全透明,只是Kirill的绝对声明是极其野心勃勃的,考虑到很多情况下,与C++有关的决策在公开的广告中已经引起了公众的厌恶。我不知道这是否是其中之一,我只是厌倦了语言设计是程序员不必去思考或好奇的东西。“重返工作岗位,劳动单位德赫希”——)至于原因,我建议在这里提问:我认为,TOuter::TInner是部分专用的,而TInner是完全专用的,但类型不完整;-)假设您在TOuter::TInner-should中犯了“语义错误”(或者只是引用了一个不存在的符号)
namespace detail
{
  template <class T, class U>
  struct InnerImpl {};
}

template <class T>
struct Outer
{
  template <class U>
  struct Inner: detail::InnerImpl<T,U>
  {
  };
};