是否有一种方法可以将可变参数包中的所有类指定为模板的友类,以便使用operator=

Is there a way to specify all classes in a variadic parameter pack to be friend of the template in order to use operator=?

本文关键字:operator 方法 一种 变参 是否 包中 参数      更新时间:2023-10-16

我看到过一个CRTP解决方案,它将接口提取到基类中,并将每个基类中的一个pack参数列为好友。然后最派生的类继承所有友基类并实现接口。

我不能使用这种方法,因为我需要保护赋值操作符,它不是继承的。

而且,由于赋值操作符的定义签名只有一个参数,因此不能使用密钥模式。

这是我想要的:

template <typename... F>
struct A {
protected:
    A& operator=(const SomeClass &other) {
        //...
    }
private:
    //I would like to do the following, but it does not work
    friend F...;
}

有办法做我需要什么?

你总是可以耍阴招。首先,定义一个重复宏:

#define REPEAT_2(M, N) M(N) M(N+1)
#define REPEAT_4(M, N)   REPEAT_2  (M, N) REPEAT_2(M, N+2)
#define REPEAT_8(M, N)   REPEAT_4  (M, N) REPEAT_4(M, N+4)
#define REPEAT_16(M, N)  REPEAT_8  (M, N) REPEAT_8(M, N+8)
#define REPEAT_32(M, N)  REPEAT_16 (M, N) REPEAT_16(M, N+16)
#define REPEAT_64(M, N)  REPEAT_32 (M, N) REPEAT_32(M, N+32)
#define REPEAT_128(M, N) REPEAT_64 (M, N) REPEAT_64(M, N+64)

然后将128个友元声明放入您选择的可变类模板中:

template <typename... T>
class A
{
    #define FRIEND(N) friend std::tuple_element_t<
                       std::min((std::size_t)N+1, sizeof...(T)), std::tuple<void, T...>>;
    REPEAT_128(FRIEND, 0)
    static constexpr int i = 3;
};
struct X; struct Y; struct Z;
using ASpec = A<X, Y, Z>;
struct X {int i = ASpec::i;};
struct Y {int i = ASpec::i;};
struct Z {int i = ASpec::i;};
template class A<>; // Small test for empty pack

。感谢@dyp。

如果您可以访问Boost。预处理器,整个东西可以用BOOST_PP_REPEAT写得更简洁。