gpt4 book ai didi

c++ - 匿名命名空间中模板化类的友元

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:35 25 4
gpt4 key购买 nike

声明类时A作为类(class)的 friend B , 而 A在匿名命名空间和 B 中定义在外部,一些编译器会产生错误“protected member inaccessible”,而其他编译器不会产生任何错误或警告。如果AB或者两者都是模板:

namespace {
template <class T>
struct A {
template <class BB>
void foo(BB const& b) { b.bar(); }
};
} // end anonymous namespace

template <class T>
class B {
template <class> friend struct A;

protected:
void bar() const {}
};

int main() {
A<int> a;
a.foo(B<int>{});
}
  1. AB都是模板。然后 Intel icc 18: error #308: function "B<T>::bar [with T=int]" is inaccessible , gcc 7.2: 没有错误, clang 5.0: 没有错误
  2. A B 时没有模板是模板:Intel icc 18:没有错误,gcc 7.2:错误:'void B<T>::bar() const [with T = int]' is protected within this context , clang 5: 没有错误
  3. A是一个模板,而 B不是:英特尔 icc 18:错误 #308 , gcc 7.2: 错误, clang 5: 没有错误
  4. 都不是A也不B是模板:Intel icc 18:没有错误,gcc 7.2:错误,clang 5:没有错误
  5. 都不是A也不B是模板(如 4.)但是 A 的位置和 B已交换:英特尔 icc 18:错误 #308 , gcc 7.2: error, clang 5: error: 'bar' is a protected member of 'B'
  6. AB都是模板(如 1.)但是 A 的位置和 B已交换:英特尔 icc 18:错误 #308 , gcc 7.2: 没有错误, clang 5: error

请参阅编译器资源管理器中的示例:https://godbolt.org/g/6Zdr3chttps://godbolt.org/g/BRqf78对于案例 6.

那么,什么是正确的行为呢?哪个编译器是正确的?

最佳答案

据我从标准判断,给定的代码在情况 1-4 中是正确的,并且应该在没有诊断的情况下编译:

未命名命名空间的定义 (7.3.1.1:1) 声明未命名命名空间定义等同于使用翻译单元唯一的名称定义命名命名空间,然后使用 using 指令导入此命名空间。

这将使 A 的声明在全局范围内可访问,并根据段落 11.3:9

A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.

因此参数化类 AB 的友元,应该能够访问 B::bar

情况 5 有所不同。据我所知,友元声明在封闭范围内声明了一个新的参数化类 A,它不同于未命名命名空间中的类 A

关于c++ - 匿名命名空间中模板化类的友元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48270533/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com