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

在类模板的其他未定义成员类的显式专门化中定义隐藏友元合法吗?

郜俊健
2023-03-14

根据[temp.expl.spec]合法放置显式专门化的规则并不完全容易掌握,特别是当与隐藏的朋友混合时,为了避免牺牲我的专门化和朋友函数[temp.expl.spec]/8我希望对以下内容发表第二个意见(1):

  • 在类模板的头文件中,在类模板的未定义(/仅声明)成员类的显式专门化中定义隐藏的友元是否合法?假设此标头包含在至少两个不同的翻译单元中。

(1)我自己对标准的解释是,根据下面的标准引用,答案是“是的;这是合法的”。

或者,举一个例子:下面的程序格式良好吗?

// s.h
#pragma once

template <int N>
struct S {
    struct M;
};
      
template<>
struct S<42>::M {
    friend int f(M) { return 42; }
};

// foo.h
#pragma once
void foo();

// foo.cpp
#include "foo.h"
#include <iostream>
#include "s.h"

void foo() {
    std::cout << f(S<42>::M{});
}

// main.cpp
#include <iostream>
#include "foo.h"
#include "s.h"

int main() {
    std::cout << f(S<42>::M{});
    foo();
}

CLANG和GCC都接受上述内容,但如果程序是格式不良的NDR或具有未定义的行为,这可能并不重要。GCC 10.1.0 DEMO,Clang 10.0.0 DEMO.

共有1个答案

施彦
2023-03-14

是的,模板类(包括类模板和类模板的成员类)的显式专门化是一个类,因此在通常情况下允许多个定义。这些定义被视为程序中只有一个定义,所以f也可以。(不清楚隐式内联在这里有什么作用,因为F只有一个定义,以至于整个S<42>::M只有一个定义。)这里缺少s ::m 的定义也没有任何意义;像这样的“成员显式专门化”实际上是封闭类模板S的缩写专门化,因此S<42>::m与此完全无关。

 类似资料:
  • 考虑上面的代码,在中,它是成员类模板成员的明确专门化定义。一些规则将适用于以下规定: 临时雇员爆炸。规格#5 显式特化类的成员不会从类模板的成员声明中隐式实例化;相反,如果需要定义,则应显式定义类模板特化的成员本身。在这种情况下,类模板显式特化的定义应在定义成员时处于范围内。显式特化类的定义与生成的特化的定义无关。也就是说,其成员不必与生成的特化的成员具有相同的名称、类型等。显式特化类模板的成员的

  • 这里有一个最小的例子来说明我遇到的问题。 模板成员显式专用于基类中的。模板的代码是显式生成的,并在成员中调用。 我发现的第一个问题是: 该错误是由于在main中调用造成的。可以通过调用来避免这种情况。为什么在的实例中显然是不可见的?

  • 关于下一个代码,我有一些问题: > 类专业化

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 问题内容: Helm允许在Kubernetes的资源文件中使用Go模板。 通常使用一个名为的文件通过以下语法定义Go模板助手: 然后可以在资源文件中使用它,如下所示: 问题 如何在其他帮助程序定义中使用定义的帮助程序? 例如,如果我有一个用于应用程序名称的助手,并想在定义入口主机名的助手的定义中使用该助手,该怎么办? 我尝试了几种其他方式来调用其他定义中的帮助器。鉴于此基本辅助功能: 我尝试了以下