类模板的成员模板的成员模板的这种显式模板功能专业化有效吗?

Fai*_*ali 5 c++ templates specialization template-specialization language-lawyer

谁知道这个明确的专业化是否有效:

template <class>
struct L {
  template <typename T>
  struct O {
    template <typename U>
    static void Fun(U);
  };
};

template<>
template<typename T>
template<typename U>
void L<int>::O<T>::Fun(U) {}
Run Code Online (Sandbox Code Playgroud)

lang主干(2013年12月3日)出现以下错误:
f:... \ test.cpp:36:20:错误:类'O'中'Fun'的脱机定义(未定义)

void L<int>::O<T>::Fun(U) {}
     ~~~~~~~~~~~~~~^
Run Code Online (Sandbox Code Playgroud)

产生1个错误。

该标准的任何支持参考,以证明您的回答是正确的!

注意:我有些奇怪,这是一个错误-我希望对任何以“ Fun”开头的模板参数系列都选择专门化的格式 <int><?any><?any>.

这是Clang错误还是我期望中的错误?

谢谢!

======编辑(我想我有一个答案)========

好的-我想我找到了支持的措辞-来自N3797(芝加哥2013年后工作草案)-14.7.3 / 16 =>

“在对类模板的成员或出现在名称空间范围中的成员模板的显式专门化声明中,成员模板及其某些封闭的类模板可能保持非专门化,除非声明在以下情况下不得显式专门化类成员模板:它的封闭类模板也没有明确地专门化。”

如果我正确地解释了这一点,那么如果要声明其成员的显式专业化,我们需要O的显式专业化?因此,错误。

正确?

谢谢!

Who*_*aig 4

我不相信这是有效的。我对语言的了解不够深入,无法告诉您如何/是否可以在不提供如下所示的顶级专业化的情况下执行此操作,或者是否有跳过复制模板的快捷方式,但错误消息相当清晰:您试图提供依赖嵌套类型的静态成员的实现,而不提供实际依赖项的专门化。即这有效:

#include <iostream>

template <typename>
struct L
{
    template <typename T>
    struct O
    {
        template <typename U>
        static void Fun(U)
        {
            std::cout << "General: " << __PRETTY_FUNCTION__ << std::endl;
        };
    };
};

// provide specialized L
template<>
struct L<int>
{
    template <typename T>
    struct O
    {
        template <typename U>
        static void Fun(U);
    };
};

// L<int> is a specialized type, so provide the rest.
template<typename T>
template<typename U>
void L<int>::O<T>::Fun(U)
{
    std::cout << "Special: " << __PRETTY_FUNCTION__ << std::endl;
}


int main()
{
    L<int>::O<double> nobj;
    nobj.Fun(10);

    L<double>::O<int> nobj2;
    nobj2.Fun(20);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

Special: static void L<int>::O<double>::Fun(U) [T = double, U = int]
General: static void L<double>::O<int>::Fun(U) [T = int, U = int]
Run Code Online (Sandbox Code Playgroud)