类如何声明其所有可变参数模板参数?

问题描述 投票:0回答:2

如果我有一个类采用模板参数的可变参数包,我怎样才能将它们声明为朋友?

这是我想以伪代码形式执行的操作:

template<typename... Ts>
class AbstractMyClass {
    int privateInt;
    friend Ts...;
};
class OtherClass;
using MyClass = AbstractMyClass<OtherClass>;

class OtherClass {
public:
    void foo(MyClass &c){
        c.privateInt = 42;
    }
};
c++ metaprogramming variadic-templates
2个回答
0
投票

以下是万能钥匙习语的稍微扩展形式,怎么样?
使用 TPassKeys,它允许将多个类指定为限制访问的函数的参数,并且在访问它时,会在允许的类中创建 TPassKey 的实例,并将其传递给 TPassKeys 的构造函数。
一个不方便的地方是,与通常的密钥习惯用法不同,调用参数不能缩写为 {}。

template <class TAuthorized>
struct TPassKey
{
private:
  friend TAuthorized;
  TPassKey() {}

public:
  TPassKey(const TPassKey&) = delete;
  TPassKey& operator=(const TPassKey&) = delete;
};

template <typename TTest, typename... TList>
struct TContains;
template<typename TTest, typename TFirst, typename... TRest>
struct TContains<TTest, TFirst, TRest...> : std::conditional_t<std::is_same_v<TTest, TFirst>, std::true_type, TContains<TTest, TRest...>> {};
template <typename TTest>
struct TContains<TTest> : std::false_type {};

template<class... TAuthorizedList>
struct TPassKeys
{
  template <class TAuthorized, typename TEnableIf<TContains<TAuthorized, TAuthorizedList...>::value, std::nullptr_t>::Type = nullptr>
  TPassKeys(TPassKey<TAuthorized>) {}
};

// Tests.
class FTest
{
public:
  static void Test(TPassKeys<class FClassA, class FClassB>) {}
};

class FClassA
{
public:
  void Test()
  {
    FTest::Test(TPassKey<FClassA>()); // OK.
  }
};

class FClassB
{
  void Test()
  {
    FTest::Test(TPassKey<FClassB>()); // OK.
  }
};

class FClassC
{
  void Test()
  {
    FTest::Test(TPassKey<FClassC>()); // Error.
  }
};

-1
投票

这只能使用“编译时递归”来完成,就像元组一样。要点是(我现在在一台小型笔记本电脑上,根本无法舒适地打字):

template<class .... THINGS> class object;

template<class T> class object {
    friend T;
};

template<class T,class ... THINGS>
class object: public object<THINGS> {
    friend T;
};

如果 C++ 不喜欢这样,请尝试使用

template<> class object<> {};
作为结束递归的递归(我在 1 个模板参数中使用
object
来终止递归)

(感谢 Dietmar Kuhl 进行格式化)

© www.soinside.com 2019 - 2024. All rights reserved.