在此代码中组合好友和模板是否有效?

Is it valid to combine friending and templating in this code?

提问人:Heather 提问时间:11/10/2023 最后编辑:Heather 更新时间:11/10/2023 访问量:60

问:

此代码在 GCC、clang 等中编译

template <int a, typename T>
class A{
        private:
                int B=1;

        friend A<-a, T> func(A a_in){
                A<-a, T> val;
                val.B = 10;
                return val;
        }
};

int main(){
  A<1, int> mya;
  auto bb= func(mya);
}

但我正在尝试使 func 成为这样的模板化函数:

template <int a, typename T>
class A{
        template<int, typename> friend class A;
        private:
                int B=1;

        public:
template<typename num>
        friend A<-a, T> func(A a_in, num num_in){
                A<-a, T> val;
                val.B = 10;
                return val;
        }
};

int main(){
A<1, int> mya;
auto bbb= func(mya, 1);
}

无论是否明确与其他 A 交好友,都可以在 clang 中工作,只要这样做,就可以在 13 或更高版本的 g++ 中工作。 在这种情况下,较旧的 g++ 抱怨 B 成员的隐私

error: ‘int A<-1, int>::B’ is private within this context
   14 |                 val.B = 10;

奇怪的是,如果我尝试在调用中明确地专门化(即),它也会给出“错误:'func'未在此范围内声明”的错误,除非我还指定了 std=c++20,这表明代码可能正在做一些定义不明确的事情。auto bb= func<int>(mya, 1);

问题:

  1. 这应该起作用,还是某种部分专业化,不应该像那样成为朋友?
  2. 为什么 clang 允许访问 A 的私有成员,即使对于不同的模板参数,为什么 gcc 也允许它用于 func 的单参数版本?我认为每个专业实际上都是一个不同的班级。
  3. 有没有其他方法可以访问A其他专业的私人成员?
++ 的 C++14

评论


答: 暂无答案