C++ 类内可能的模板专门化

C++ 类内可能的模板专门化,c++,C++,我遇到了如下代码: class XX { public: template<typename TT> struct YY; template<typename TT, typename UU> struct YY<std::pair<TT, UU>> { std::size_t operator()(std::pair<TT, UU> const& val) const

我遇到了如下代码:

class XX
{
public:
    template<typename TT> struct YY;

    template<typename TT, typename UU> struct YY<std::pair<TT, UU>>
    {
        std::size_t operator()(std::pair<TT, UU> const& val) const
        {
            // content omitted for brevity
        }
    };
};
XX类
{
公众:
模板结构YY;
模板结构YY
{
std::size\u t运算符()(std::pair const&val)const
{
//为简洁起见省略了内容
}
};
};
基本上,我很困惑,需要帮助理解这段代码

具体而言,第一份YY声明是否为远期声明?第二个YY声明是部分模板专门化吗?为什么第二个YY声明有两个模板参数(TT和UU),而第一个YY声明只有一个模板参数(TT)?为什么第一个YY声明没有定义

(代码编译时没有问题。)

具体而言,第一份YY声明是否为远期声明

对。这使得任何实例化
YY
都是不完整的类型,除了

第二个YY声明是部分模板专门化吗

。。。如果有一个特定类型或类型类(如指针)的模板专门化,它提供了完整的定义。在这种特殊情况下,这确实是一种局部特化,适用于所有
YY
,其中
T
TT
UU
的成对类型

为什么第二个YY声明有两个模板参数(TT和UU),而第一个YY声明只有一个模板参数(TT)

代码的作者不想对这对类型强加任何条件,它们应该是任意的。通过编写这样的专门化,您基本上可以将所有采用
std::pair
YY
实例化提升为具有两个参数的模板

为什么第一个YY声明没有定义


因为它可能不需要。创建专门化所需的只是一个声明。如果您在那里实际定义了
YY
,则会得到一个“默认”实例化,在没有专门化的情况下,该实例化始终会被实例化。如果您希望在选择没有专门化的类型时编译失败,您可以这样做。或者(可能更好),您实际上应该定义模板,包含
静态断言(!std::is\u same\u v)
或类似的内容,以及比“无法创建不完整类型的对象”之类的内容更有意义的消息。

但是
静态断言(false)
会使程序格式错误,因此,您必须依靠技巧使
false
以某种方式依赖于模板参数:)@Quentin-True,但详细说明这一点会使答案过于臃肿。这里已经有太多的问题了。