当前位置: 首页 > 知识库问答 >
问题:

类模板的成员模板的成员模板的显式模板函数特化有效吗?

周楷
2023-03-14

是否有人知道此显式特化是否有效:

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) {}

clang 主干 (12/3/2013) 给出以下错误:
f:...\test.cpp:36:20: 错误: 从类 'O' 中出线定义 “Fun” 没有定义

void L<int>::O<T>::Fun(U) {}
     ~~~~~~~~~~~~~~^

1生成错误。

任何来自标准的支持参考来证明你的答案将不胜感激!

注意:我有点惊讶这是一个错误——我认为应该为任何以< code >开始实例化“Fun”的模板参数族选择专门化

这是一个叮当的错误还是我期望中的错误?

谢谢!

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

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

在出现在命名空间范围内的类模板或成员模板的成员的显式专用化声明中,成员模板和它的一些封闭类模板可以保持非专用化,除非如果它的封闭类模板也没有显式专用化,则声明不应显式专用化类成员模板

如果我没理解错的话,我们需要O的显式专门化,如果我们要声明它的成员的显式专门化?因此出现了错误。

正确吗?

谢谢!

共有1个答案

高功
2023-03-14

我不相信它是有效的。我在语言方面还不够深入,无法告诉您如何/是否可以在不提供顶级专门化的情况下做到这一点,或者是否有跳过复制模板的捷径,但错误消息相当清楚:您试图提供依赖嵌套类型的静态成员的实现,而不提供实际依赖的专门化。也就是说,这是可行的:

#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;
}

输出

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]
 类似资料:
  • 我有一个模板化的C++类,它也有一个模板化的成员函数。这个成员函数的模板参数以特定的方式依赖于类的模板参数(请参阅下面的代码)。我正在为其模板参数的两个不同值实例化(而不是专门化)该类。一切都在这一点上进行。但是,如果我调用模板化的成员函数,对第一个实例化对象的调用只会编译,而不会编译第二个。似乎编译器没有为模板类的第二次实例化实例化模板化成员函数。我正在使用“g++filename.cpp”编译

  • 我有一个问题,我想在下面的代码中专门化模板类的模板成员函数。这个问题的答案是模板类成员函数的显式特化,这似乎表明它无法完成。这是正确的吗,如果是这样,我可以使用任何解决方法,以便在编译时通过内联inc函数进行扩展? 非常感谢! g吐槽道: test2.cpp:32:13: 错误: 非命名空间作用域中的显式专用化 'struct IdxIterator' test2.cpp:32:25: 错误: 非

  • 我试图用成员模板函数实现一个可变类模板,其模板参数独立于类模板参数,但在定义成员模板时遇到了问题。 我将问题简化为尝试编译此文件(抱歉,无法进一步简化): 在尝试编译(C 11)时,我遇到以下错误: 我很确定它归结为第一个和第五个错误,但不知道我做错了什么。为什么

  • 我试图在变量函数模板上使用'decltype'来获取其返回值类型,然后使用它来定义成员变量。但我一直在犯这样的错误: 基本上,decltype失败并将声明为int,而不是推断的返回类型。 它的工作原理是当我提供的所有参数的值,但这不是我要找的行为。因为我不知道该函数有多少参数,所以它必须保持为可变模板函数。 我计划如何使用类模板的示例: 如果我没有任何成员变量,并使用作为: 它编译,因此我相信能够

  • 这有什么问题: 我在这里尝试过:用不同的编译器https://godbolt.org/z/NkL44s: x86-64 gcc 9.2:编译 x86-64 gcc(主干):失败 x86-64 clang 6.0.0:编译 x86-64 clang 7.0.0及更高版本:失败 x64 msvc v19.22:编译 x64 msvc v19.23(内部测试):失败 那么,为什么最近的编译器会拒绝这一点