You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将模板模板参数传入的所有类型声明为MyStruct的友元?

让传入MyStruct的模板类型自动成为友元的两种实现方案

方案一:精准授权当前传入的子类型

如果只想让当前MyStruct实例所使用的SUB_TYPE模板特化类型成为友元(最安全的方式),只需将MyStruct中的友元声明替换为:

friend struct SUB_TYPE<MyStruct>;

修改后的完整代码:

template<typename MyStructType>
struct OTHER_SUB_TYPE {
  OTHER_SUB_TYPE(MyStructType* p) {  p->private_function(); }
  // 可访问MyStructType的其他私有成员
};

template<typename MyStructType>
struct DEFAULT_SUB_TYPE {
  DEFAULT_SUB_TYPE(MyStructType* p) { p->private_function(); }
  // 可访问MyStructType的其他私有成员
};

template<template<typename> class SUB_TYPE = DEFAULT_SUB_TYPE>
struct MyStruct {
  SUB_TYPE<MyStruct> Get() { return SUB_TYPE{this}; }

  // 仅授权当前使用的SUB_TYPE特化版本为友元
  friend struct SUB_TYPE<MyStruct>;

private:
  void private_function() {}
};


int main() {
  MyStruct<> def;
  def.Get();

  MyStruct<OTHER_SUB_TYPE> other;
  other.Get();
}

原理说明

  • SUB_TYPE<MyStruct>就是当前MyStruct实例对应的子类型特化(比如DEFAULT_SUB_TYPE<MyStruct<>>或OTHER_SUB_TYPE<MyStruct<OTHER_SUB_TYPE>>)
  • 这种写法只会让当前传入的子类型获得友元权限,不会开放给无关类型,安全性更高。

方案二:开放所有符合模板形式的子类型

如果需要所有满足template<typename> class形式的模板结构体都能成为MyStruct的友元(适合需要大量不同子类型的场景),可以使用模板模板参数的友元声明:

template<template<typename> class FriendSubType>
friend struct FriendSubType;

修改后的完整代码:

template<typename MyStructType>
struct OTHER_SUB_TYPE {
  OTHER_SUB_TYPE(MyStructType* p) {  p->private_function(); }
  // 可访问MyStructType的其他私有成员
};

template<typename MyStructType>
struct DEFAULT_SUB_TYPE {
  DEFAULT_SUB_TYPE(MyStructType* p) { p->private_function(); }
  // 可访问MyStructType的其他私有成员
};

template<template<typename> class SUB_TYPE = DEFAULT_SUB_TYPE>
struct MyStruct {
  SUB_TYPE<MyStruct> Get() { return SUB_TYPE{this}; }

  // 授权所有单类型参数的模板结构体为友元
  template<template<typename> class FriendSubType>
  friend struct FriendSubType;

private:
  void private_function() {}
};


int main() {
  MyStruct<> def;
  def.Get();

  MyStruct<OTHER_SUB_TYPE> other;
  other.Get();

  // 自定义子类型也能自动获得友元权限
  template<typename T>
  struct CUSTOM_SUB_TYPE {
    CUSTOM_SUB_TYPE(T* p) { p->private_function(); }
  };

  MyStruct<CUSTOM_SUB_TYPE> custom;
  custom.Get();
}

原理说明

  • 这条友元声明表示:任何以单个类型为模板参数的结构体,都将成为当前MyStruct实例的友元。
  • 无需手动逐个添加子类型的友元声明,新的子类型只要符合模板形式就能直接访问MyStruct的私有成员。

内容的提问来源于stack exchange,提问作者Wad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:15:39