有没有一种方法可以指定可变参数包中的所有类作为模板的好朋友,以便使用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=?

查看:37
本文介绍了有没有一种方法可以指定可变参数包中的所有类作为模板的好朋友,以便使用operator =?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过CRTP解决方案,它将接口提取到基类中,并且每个基类仅将pack参数之一作为好友.然后,派生程度最高的类继承了所有友好的基类并实现了接口.

I have seen a CRTP solution, which extracted the interface into the base class, and friended only one of the pack arguments per base class. Then the most derived class inherited all the friended base classes and implemented the interface.

我不能使用这种方法,因为我需要保护不继承的赋值运算符.

I cannot use this approach, since I need to protect the assignment operator, which is not inherited.

此外,由于赋值运算符具有仅带有一个参数的已定义签名,因此我不能使用

Also, since the assignment operator has a defined signature with exactly one parameter, I cannot use a key pattern.

这就是我想要的:

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...;
}

有没有办法做我需要做的事?

Is there a way to do what I am needing?

推荐答案

好吧,您总是可以轻描淡写.首先,定义一个重复宏:

Well, you can always play dirty. First, define a repetition macro:

#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个朋友声明放入您选择的可变参数类模板中:

Then place 128 friend declarations into a variadic class template of your choice:

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.

Demo. Credit to @dyp.

如果您有权使用Boost.Preprocessor,则可以使用 BOOST_PP_REPEAT 更加简洁地编写整个内容.

If you have access to Boost.Preprocessor, the entire thing can be written far more concisely using BOOST_PP_REPEAT.

这篇关于有没有一种方法可以指定可变参数包中的所有类作为模板的好朋友,以便使用operator =?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆